5.0.2 20170503
* Reset SaveData, SaveState and MqttResponse to default values due to
rearranging settings
* Moved some settings flag area
* Add command TempUnit Celsius|Fahrenheit for selecting Celsius or
Fahrenheit (#347)
* Add command TempRes 0..3 for selecting Temperature Resolution (#347)
* Add command HumRes 0..3 for selecting Humidity Resolution (#347)
* Add command PressRes 0..3 for selecting Pressure Resolution (#347)
* Add command EnergyRes 0..5 for selecting Energy Resolution (#347)
* Add "TemperatureUnit":"C|F" to sensor JSON output (#347)
* Add support for up to three DHT type sensors each using a different
GPIO (#339, #404)
This commit is contained in:
arendst 2017-05-03 18:19:13 +02:00
parent 1dcde6aac4
commit c61a39a06d
18 changed files with 488 additions and 364 deletions

View File

@ -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 **5.0.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
Current version is **5.0.2** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
### **** ATTENTION Version 5.0.x specific information ****
@ -11,7 +11,7 @@ Best practice to implement is:
- Open the webpage to your device
- Perform option ``Backup Configuration``
- Upgrade new firmware using ``Firmware upgrade``
- If configuration conversion failed keep the webpage open and perform ``Restore Configuration``
- If configuration conversion fails keep the webpage open and perform ``Restore Configuration``
You should now have a device with 32k more code memory to play with.

Binary file not shown.

View File

@ -1,4 +1,15 @@
/* 5.0.1 20170429
/* 5.0.2 20170503
* Reset SaveData, SaveState and MqttResponse to default values due to rearranging settings
* Moved some settings flag area
* Add command TempUnit Celsius|Fahrenheit for selecting Celsius or Fahrenheit (#347)
* Add command TempRes 0..3 for selecting Temperature Resolution (#347)
* Add command HumRes 0..3 for selecting Humidity Resolution (#347)
* Add command PressRes 0..3 for selecting Pressure Resolution (#347)
* Add command EnergyRes 0..5 for selecting Energy Resolution (#347)
* Add "TemperatureUnit":"C|F" to sensor JSON output (#347)
* Add support for up to three DHT type sensors each using a different GPIO (#339, #404)
*
* 5.0.1 20170429
* Adjust Sonoff SC messages to prepare for display feature
* Move static data from RAM to Flash
* Fix PowerOnState for some devices not reporting "Power on" state (#284, #380, #383)

View File

@ -2,21 +2,49 @@
* Config settings
\*********************************************************************************************/
typedef struct {
uint32_t savestate : 1;
uint32_t button_restrict : 1;
uint32_t value_units : 1;
uint32_t mqtt_enabled : 1;
uint32_t mqtt_response : 1;
uint32_t mqtt_power_retain : 1;
uint32_t mqtt_button_retain : 1;
uint32_t mqtt_switch_retain : 1;
uint32_t temperature_conversion : 1;
uint32_t spare23 : 1;
uint32_t spare22 : 1;
uint32_t spare21 : 1;
uint32_t spare20 : 1;
uint32_t spare19 : 1;
uint32_t spare18 : 1;
uint32_t spare17 : 1;
uint32_t spare16 : 1;
uint32_t spare15 : 1;
uint32_t spare14 : 1;
uint32_t spare13 : 1;
uint32_t spare12 : 1;
uint32_t emulation : 2;
uint32_t energy_resolution : 3;
uint32_t pressure_resolution : 2;
uint32_t humidity_resolution : 2;
uint32_t temperature_resolution : 2;
} sysBitfield;
struct SYSCFG {
unsigned long cfg_holder;
unsigned long saveFlag;
unsigned long version;
unsigned long bootcount;
byte migflg; // Not used since 3.9.1
sysBitfield flag; // Add flag since 5.0.2
int16_t savedata;
byte savestate;
byte mqtt_response; // was model until 3.9.1
int8_t timezone;
char otaUrl[101];
char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5
char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5
byte serial_enable;
byte serial_enable; // Not used (ever)
byte seriallog_level;
uint8_t sta_config;
byte sta_active;
@ -39,10 +67,10 @@ struct SYSCFG {
char button_topic[33];
char mqtt_grptopic[33];
char state_text[3][11]; // was ex_mqtt_subtopic[33] until 4.1.1
byte mqtt_button_retain;
byte mqtt_power_retain;
byte value_units;
byte button_restrict; // Was message_format until 3.2.6a
byte ex_mqtt_button_retain; // Not used since 5.0.2
byte ex_mqtt_power_retain; // Not used since 5.0.2
byte ex_value_units; // Not used since 5.0.2
byte ex_button_restrict; // Not used since 5.0.2
uint16_t tele_period;
uint8_t power;
@ -77,7 +105,7 @@ struct SYSCFG {
uint16_t hlw_mkwhs; // MaxEnergyStart
// 3.0.6
uint16_t ex_pulsetime; // Not used since 4.0.4
uint16_t ex_pulsetime; // Not used since 4.0.4
// 3.1.1
uint8_t poweronstate;
@ -104,8 +132,8 @@ struct SYSCFG {
// 3.2.8
char switch_topic[33];
byte mqtt_switch_retain;
uint8_t mqtt_enabled;
byte ex_mqtt_switch_retain; // Not used since 5.0.2
uint8_t ex_mqtt_enabled; // Not used since 5.0.2
// 3.2.12
uint8_t sleep;
@ -126,7 +154,7 @@ struct SYSCFG {
uint16_t led_wakeup;
// 3.9.7
uint8_t emulation;
uint8_t ex_emulation; // Not used since 5.0.2
// 3.9.20
char web_password[33];

View File

@ -277,7 +277,7 @@ void CFG_Erase()
}
}
void CFG_Dump()
void CFG_Dump(uint16_t srow, uint16_t mrow)
{
#define CFG_COLS 16
@ -288,9 +288,19 @@ void CFG_Dump()
uint16_t col;
uint8_t *buffer = (uint8_t *) &sysCfg;
row = 0;
maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS);
if ((srow > 0) && (srow < maxrow)) {
row = srow;
}
if (0 == mrow) { // Default only four lines
mrow = 4;
}
if ((mrow > 0) && (mrow < (maxrow - row))) {
maxrow = row + mrow;
}
for (row = 0; row < maxrow; row++) {
for (row = srow; row < maxrow; row++) {
idx = row * CFG_COLS;
snprintf_P(log, sizeof(log), PSTR("%04X:"), idx);
for (col = 0; col < CFG_COLS; col++) {
@ -313,25 +323,35 @@ void CFG_Dump()
/********************************************************************************************/
void CFG_Default()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration"));
CFG_DefaultSet1();
CFG_DefaultSet2();
CFG_Save();
}
void CFG_DefaultSet1()
{
memset(&sysCfg, 0x00, sizeof(SYSCFG));
sysCfg.cfg_holder = CFG_HOLDER;
sysCfg.saveFlag = 0;
// sysCfg.saveFlag = 0;
sysCfg.version = VERSION;
sysCfg.bootcount = 0;
// sysCfg.bootcount = 0;
}
void CFG_DefaultSet2()
{
memset((char*)&sysCfg +16, 0x00, sizeof(SYSCFG) -16);
sysCfg.flag.savestate = SAVE_STATE;
sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE;
sysCfg.timezone = APP_TIMEZONE;
strlcpy(sysCfg.otaUrl, OTA_URL, sizeof(sysCfg.otaUrl));
sysCfg.seriallog_level = SERIAL_LOG_LEVEL;
sysCfg.sta_active = 0;
// sysCfg.sta_active = 0;
strlcpy(sysCfg.sta_ssid[0], STA_SSID1, sizeof(sysCfg.sta_ssid[0]));
strlcpy(sysCfg.sta_pwd[0], STA_PASS1, sizeof(sysCfg.sta_pwd[0]));
strlcpy(sysCfg.sta_ssid[1], STA_SSID2, sizeof(sysCfg.sta_ssid[1]));
@ -353,10 +373,10 @@ void CFG_DefaultSet2()
strlcpy(sysCfg.mqtt_topic, MQTT_TOPIC, sizeof(sysCfg.mqtt_topic));
strlcpy(sysCfg.button_topic, "0", sizeof(sysCfg.button_topic));
strlcpy(sysCfg.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(sysCfg.mqtt_grptopic));
sysCfg.mqtt_button_retain = MQTT_BUTTON_RETAIN;
sysCfg.mqtt_power_retain = MQTT_POWER_RETAIN;
sysCfg.value_units = 0;
sysCfg.button_restrict = 0;
sysCfg.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN;
sysCfg.flag.mqtt_power_retain = MQTT_POWER_RETAIN;
// sysCfg.flag.value_units = 0;
// sysCfg.flag.button_restrict = 0;
sysCfg.tele_period = TELE_PERIOD;
sysCfg.power = APP_POWER;
@ -371,31 +391,31 @@ void CFG_DefaultSet2()
sysCfg.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER;
for (byte i = 0; i < 4; i++) {
sysCfg.switchmode[i] = SWITCH_MODE;
sysCfg.domoticz_relay_idx[i] = 0;
sysCfg.domoticz_key_idx[i] = 0;
sysCfg.domoticz_switch_idx[i] = 0;
// sysCfg.domoticz_relay_idx[i] = 0;
// sysCfg.domoticz_key_idx[i] = 0;
// sysCfg.domoticz_switch_idx[i] = 0;
}
sysCfg.hlw_pcal = HLW_PREF_PULSE;
sysCfg.hlw_ucal = HLW_UREF_PULSE;
sysCfg.hlw_ical = HLW_IREF_PULSE;
sysCfg.hlw_kWhtoday = 0;
sysCfg.hlw_kWhyesterday = 0;
sysCfg.hlw_kWhdoy = 0;
sysCfg.hlw_pmin = 0;
sysCfg.hlw_pmax = 0;
sysCfg.hlw_umin = 0;
sysCfg.hlw_umax = 0;
sysCfg.hlw_imin = 0;
sysCfg.hlw_imax = 0;
sysCfg.hlw_mpl = 0; // MaxPowerLimit
// sysCfg.hlw_kWhtoday = 0;
// sysCfg.hlw_kWhyesterday = 0;
// sysCfg.hlw_kWhdoy = 0;
// sysCfg.hlw_pmin = 0;
// sysCfg.hlw_pmax = 0;
// sysCfg.hlw_umin = 0;
// sysCfg.hlw_umax = 0;
// sysCfg.hlw_imin = 0;
// sysCfg.hlw_imax = 0;
// sysCfg.hlw_mpl = 0; // MaxPowerLimit
sysCfg.hlw_mplh = MAX_POWER_HOLD;
sysCfg.hlw_mplw = MAX_POWER_WINDOW;
sysCfg.hlw_mspl = 0; // MaxSafePowerLimit
// sysCfg.hlw_mspl = 0; // MaxSafePowerLimit
sysCfg.hlw_msplh = SAFE_POWER_HOLD;
sysCfg.hlw_msplw = SAFE_POWER_WINDOW;
sysCfg.hlw_mkwh = 0; // MaxEnergy
sysCfg.hlw_mkwhs = 0; // MaxEnergyStart
// sysCfg.hlw_mkwh = 0; // MaxEnergy
// sysCfg.hlw_mkwhs = 0; // MaxEnergyStart
CFG_DefaultSet_3_2_4();
@ -407,10 +427,10 @@ void CFG_DefaultSet2()
CFG_DefaultSet_3_9_3();
strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic));
sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.mqtt_enabled = MQTT_USE;
sysCfg.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.flag.mqtt_enabled = MQTT_USE;
sysCfg.emulation = EMULATION;
sysCfg.flag.emulation = EMULATION;
strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
@ -418,7 +438,7 @@ void CFG_DefaultSet2()
sysCfg.pulsetime[0] = APP_PULSETIME;
// 4.0.7
for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0;
// for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0;
// 4.0.9
CFG_DefaultSet_4_0_9();
@ -426,8 +446,12 @@ void CFG_DefaultSet2()
// 4.1.1
CFG_DefaultSet_4_1_1();
// 5.0.2
CFG_DefaultSet_5_0_2();
}
/********************************************************************************************/
void CFG_DefaultSet_3_2_4()
{
sysCfg.ws_pixels = WS2812_LEDS;
@ -503,18 +527,18 @@ void CFG_DefaultSet_4_0_9()
void CFG_DefaultSet_4_1_1()
{
sysCfg.mqtt_response = 0;
strlcpy(sysCfg.state_text[0], MQTT_STATUS_OFF, sizeof(sysCfg.state_text[0]));
strlcpy(sysCfg.state_text[1], MQTT_STATUS_ON, sizeof(sysCfg.state_text[1]));
strlcpy(sysCfg.state_text[2], MQTT_CMND_TOGGLE, sizeof(sysCfg.state_text[2]));
}
void CFG_Default()
void CFG_DefaultSet_5_0_2()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration"));
CFG_DefaultSet1();
CFG_DefaultSet2();
CFG_Save();
sysCfg.flag.temperature_conversion = TEMP_CONVERSION;
sysCfg.flag.temperature_resolution = TEMP_RESOLUTION;
sysCfg.flag.humidity_resolution = HUMIDITY_RESOLUTION;
sysCfg.flag.pressure_resolution = PRESSURE_RESOLUTION;
sysCfg.flag.energy_resolution = ENERGY_RESOLUTION;
}
/********************************************************************************************/
@ -543,8 +567,8 @@ void CFG_Delta()
}
if (sysCfg.version < 0x03020800) { // 3.2.8 - Add parameter
strlcpy(sysCfg.switch_topic, sysCfg.button_topic, sizeof(sysCfg.switch_topic));
sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.mqtt_enabled = MQTT_USE;
sysCfg.ex_mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.ex_mqtt_enabled = MQTT_USE;
}
if (sysCfg.version < 0x03020C00) { // 3.2.12 - Add parameter
sysCfg.sleep = APP_SLEEP;
@ -553,7 +577,7 @@ void CFG_Delta()
CFG_DefaultSet_3_9_3();
}
if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter
sysCfg.emulation = EMULATION;
sysCfg.ex_emulation = EMULATION;
}
if (sysCfg.version < 0x03091400) {
strlcpy(sysCfg.web_password, WEB_PASSWORD, sizeof(sysCfg.web_password));
@ -562,7 +586,7 @@ void CFG_Delta()
for (byte i = 0; i < 4; i++) sysCfg.switchmode[i] = sysCfg.ex_switchmode;
}
if (sysCfg.version < 0x04000200) {
sysCfg.button_restrict = 0;
sysCfg.ex_button_restrict = 0;
}
if (sysCfg.version < 0x04000400) {
CFG_DefaultSet_4_0_4();
@ -582,6 +606,23 @@ void CFG_Delta()
if (sysCfg.version < 0x04010100) {
CFG_DefaultSet_4_1_1();
}
if (sysCfg.version < 0x05000105) {
sysCfg.flag = { 0 };
sysCfg.flag.savestate = SAVE_STATE;
sysCfg.flag.button_restrict = sysCfg.ex_button_restrict;
sysCfg.flag.value_units = sysCfg.ex_value_units;
sysCfg.flag.mqtt_enabled = sysCfg.ex_mqtt_enabled;
// sysCfg.flag.mqtt_response = 0;
sysCfg.flag.mqtt_power_retain = sysCfg.ex_mqtt_power_retain;
sysCfg.flag.mqtt_button_retain = sysCfg.ex_mqtt_button_retain;
sysCfg.flag.mqtt_switch_retain = sysCfg.ex_mqtt_switch_retain;
sysCfg.flag.emulation = sysCfg.ex_emulation;
CFG_DefaultSet_5_0_2();
sysCfg.savedata = SAVE_DATA;
}
sysCfg.version = VERSION;
}
}

View File

@ -10,7 +10,7 @@
* ====================================================
*/
#define VERSION 0x05000100 // 5.0.1
#define VERSION 0x05000200 // 5.0.2
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};
@ -264,7 +264,7 @@ uint8_t pin[GPIO_MAX]; // Possible pin configurations
uint8_t rel_inverted[4] = { 0 }; // Relay inverted flag (1 = (0 = On, 1 = Off))
uint8_t led_inverted[4] = { 0 }; // LED inverted flag (1 = (0 = On, 1 = Off))
uint8_t swt_flg = 0; // Any external switch configured
uint8_t dht_type = 0; // DHT type (DHT11, DHT21 or DHT22)
uint8_t dht_flg = 0; // DHT configured
uint8_t hlw_flg = 0; // Power monitor configured
uint8_t i2c_flg = 0; // I2C configured
uint8_t spi_flg = 0; // SPI configured
@ -425,7 +425,7 @@ void mqtt_publish_sec(const char* topic, const char* data, boolean retained)
{
char log[TOPSZ + MESSZ];
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
if (mqttClient.publish(topic, data, retained)) {
snprintf_P(log, sizeof(log), PSTR("MQTT: %s = %s%s"), topic, data, (retained) ? " (retained)" : "");
// mqttClient.loop(); // Do not use here! Will block previous publishes
@ -465,7 +465,7 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data
char romram[16];
char stopic[TOPSZ];
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.mqtt_response) ? PSTR("RESULT") : subtopic);
snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? PSTR("RESULT") : subtopic);
prefix &= 1;
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), sysCfg.mqtt_prefix[prefix +1], sysCfg.mqtt_topic, romram);
mqtt_publish(stopic, data);
@ -482,12 +482,12 @@ void mqtt_publishPowerState(byte device)
}
snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"),
sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (sysCfg.mqtt_response)?"POWER":"RESULT");
sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response)?"POWER":"RESULT");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"POWER%s\":\"%s\"}"),
(Maxdevice > 1) ? sdevice : "", getStateText(bitRead(power, device -1)));
mqtt_publish(stopic, svalue);
json2legacy(stopic, svalue);
mqtt_publish(stopic, svalue, sysCfg.mqtt_power_retain);
mqtt_publish(stopic, svalue, sysCfg.flag.mqtt_power_retain);
}
void mqtt_publishPowerBlinkState(byte device)
@ -509,7 +509,7 @@ void mqtt_connected()
char stopic[TOPSZ];
char svalue[128]; // was MESSZ
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
// Satisfy iobroker (#299)
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/POWER"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic);
@ -563,7 +563,7 @@ void mqtt_reconnect()
mqttcounter = MQTT_RETRY_SECS;
if (!sysCfg.mqtt_enabled) {
if (!sysCfg.flag.mqtt_enabled) {
mqtt_connected();
return;
}
@ -640,9 +640,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
}
else if (!strcmp_P(type,PSTR("MQTTRESPONSE"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.mqtt_response = payload;
sysCfg.flag.mqtt_response = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttResponse\":\"%s\"}"), getStateText(sysCfg.mqtt_response));
snprintf_P(svalue, ssvalue, PSTR("{\"MqttResponse\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_response));
}
else if (!strcmp_P(type,PSTR("STATETEXT")) && (index > 0) && (index <= 3)) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) {
@ -764,9 +764,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
send_button_power(0, i, 3); // Clear MQTT retain in broker
}
}
sysCfg.mqtt_button_retain = payload;
sysCfg.flag.mqtt_button_retain = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), getStateText(sysCfg.mqtt_button_retain));
snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain));
}
else if (!strcmp_P(type,PSTR("SWITCHRETAIN"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
@ -776,9 +776,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
send_button_power(1, i, 3); // Clear MQTT retain in broker
}
}
sysCfg.mqtt_switch_retain = payload;
sysCfg.flag.mqtt_switch_retain = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), getStateText(sysCfg.mqtt_switch_retain));
snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain));
}
else if (!strcmp_P(type,PSTR("POWERRETAIN"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
@ -786,12 +786,12 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
for(i = 1; i <= Maxdevice; i++) { // Clear MQTT retain in broker
snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i);
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/POWER%s"), sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain);
mqtt_publish(stemp1, "", sysCfg.flag.mqtt_power_retain);
}
}
sysCfg.mqtt_power_retain = payload;
sysCfg.flag.mqtt_power_retain = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"PowerRetain\":\"%s\"}"), getStateText(sysCfg.mqtt_power_retain));
snprintf_P(svalue, ssvalue, PSTR("{\"PowerRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain));
}
#ifdef USE_DOMOTICZ
else if (domoticz_command(type, index, dataBuf, data_len, payload, svalue, ssvalue)) {
@ -844,7 +844,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
// if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) Serial.println(dataBuf);
#ifdef USE_DOMOTICZ
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
if (domoticz_mqttData(topicBuf, sizeof(topicBuf), dataBuf, sizeof(dataBuf))) {
return;
}
@ -901,10 +901,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
int16_t payload = atoi(dataBuf); // -32766 - 32767
uint16_t payload16 = atoi(dataBuf); // 0 - 65535
if (!strcmp_P(dataBufUc,PSTR("OFF")) || !strcmp_P(dataBufUc,PSTR("FALSE")) || !strcmp_P(dataBufUc,PSTR("STOP"))) {
if (!strcmp_P(dataBufUc,PSTR("OFF")) || !strcmp_P(dataBufUc,PSTR("FALSE")) || !strcmp_P(dataBufUc,PSTR("STOP")) || !strcmp_P(dataBufUc,PSTR("CELSIUS"))) {
payload = 0;
}
if (!strcmp_P(dataBufUc,PSTR("ON")) || !strcmp_P(dataBufUc,PSTR("TRUE")) || !strcmp_P(dataBufUc,PSTR("START")) || !strcmp_P(dataBufUc,PSTR("USER"))) {
if (!strcmp_P(dataBufUc,PSTR("ON")) || !strcmp_P(dataBufUc,PSTR("TRUE")) || !strcmp_P(dataBufUc,PSTR("START")) || !strcmp_P(dataBufUc,PSTR("FAHRENHEIT")) || !strcmp_P(dataBufUc,PSTR("USER"))) {
payload = 1;
}
if (!strcmp_P(dataBufUc,PSTR("TOGGLE")) || !strcmp_P(dataBufUc,PSTR("ADMIN"))) {
@ -970,7 +970,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
sysCfg.savedata = payload;
savedatacounter = sysCfg.savedata;
}
if (sysCfg.savestate) {
if (sysCfg.flag.savestate) {
sysCfg.power = power;
}
CFG_Save();
@ -981,28 +981,58 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
else if (!strcmp_P(type,PSTR("SAVESTATE"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.savestate = payload;
sysCfg.flag.savestate = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveState\":\"%s\"}"), getStateText(sysCfg.savestate));
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveState\":\"%s\"}"), getStateText(sysCfg.flag.savestate));
}
else if (!strcmp_P(type,PSTR("BUTTONRESTRICT"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.button_restrict = payload;
sysCfg.flag.button_restrict = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRestrict\":\"%s\"}"), getStateText(sysCfg.button_restrict));
snprintf_P(svalue, sizeof(svalue), PSTR("{\"ButtonRestrict\":\"%s\"}"), getStateText(sysCfg.flag.button_restrict));
}
else if (!strcmp_P(type,PSTR("UNITS"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.value_units = payload;
sysCfg.flag.value_units = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), getStateText(sysCfg.value_units));
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Units\":\"%s\"}"), getStateText(sysCfg.flag.value_units));
}
else if (!strcmp_P(type,PSTR("MQTT"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.mqtt_enabled = payload;
sysCfg.flag.mqtt_enabled = payload;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), getStateText(sysCfg.mqtt_enabled));
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Mqtt\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_enabled));
}
else if (!strcmp_P(type,PSTR("TEMPUNIT"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 1)) {
sysCfg.flag.temperature_conversion = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempUnit\":\"%s\"}"), (sysCfg.flag.temperature_conversion) ? "Fahrenheit" : "Celsius");
}
else if (!strcmp_P(type,PSTR("TEMPRES"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 3)) {
sysCfg.flag.temperature_resolution = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempRes\":%d}"), sysCfg.flag.temperature_resolution);
}
else if (!strcmp_P(type,PSTR("HUMRES"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 3)) {
sysCfg.flag.humidity_resolution = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"HumRes\":%d}"), sysCfg.flag.humidity_resolution);
}
else if (!strcmp_P(type,PSTR("PRESSRES"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 3)) {
sysCfg.flag.pressure_resolution = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PressRes\":%d}"), sysCfg.flag.pressure_resolution);
}
else if (!strcmp_P(type,PSTR("ENERGYRES"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 5)) {
sysCfg.flag.energy_resolution = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"EnergyRes\":%d}"), sysCfg.flag.energy_resolution);
}
else if (!strcmp_P(type,PSTR("MODULE"))) {
if ((data_len > 0) && (payload > 0) && (payload <= MAXMODULE)) {
@ -1123,7 +1153,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
sysCfg.sleep = payload;
sleep = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.value_units) ? " mS" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " mS" : "");
}
else if (!strcmp_P(type,PSTR("FLASHMODE"))) { // 0 = QIO, 1 = QOUT, 2 = DIO, 3 = DOUT
if ((data_len > 0) && (payload >= 0) && (payload <= 3)) {
@ -1157,7 +1187,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
else if (!strcmp_P(type,PSTR("SYSLOG"))) {
if ((data_len > 0) && (payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
sysCfg.syslog_level = payload;
syslog_level = (sysCfg.emulation) ? 0 : payload;
syslog_level = (sysCfg.flag.emulation) ? 0 : payload;
syslog_timer = 0;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SysLog\":\"%d (Active %d)\"}"), sysCfg.syslog_level, syslog_level);
@ -1293,10 +1323,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
#ifdef USE_EMULATION
else if (!strcmp_P(type,PSTR("EMULATION"))) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
sysCfg.emulation = payload;
sysCfg.flag.emulation = payload;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Emulation\":%d}"), sysCfg.emulation);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Emulation\":%d}"), sysCfg.flag.emulation);
}
#endif // USE_EMULATION
#endif // USE_WEBSERVER
@ -1308,7 +1338,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
tele_period = sysCfg.tele_period;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"TelePeriod\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.value_units) ? " Sec" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"TelePeriod\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.flag.value_units) ? " Sec" : "");
}
else if (!strcmp_P(type,PSTR("RESTART"))) {
switch (payload) {
@ -1371,10 +1401,26 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedState\":%d}"), sysCfg.ledstate);
}
else if (!strcmp_P(type,PSTR("CFGDUMP"))) {
CFG_Dump();
uint16_t srow = 0;
uint16_t mrow = 0;
if (data_len > 0) {
srow = payload16;
byte i = 0;
while (isdigit(dataBuf[i])) {
i++;
}
if (i < strlen(dataBuf)) {
mrow = atoi(dataBuf +i);
}
if (0 == mrow) {
mrow = payload16;
srow = 0;
}
}
CFG_Dump(srow, mrow);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"CfgDump\":\"Done\"}"));
}
else if (sysCfg.mqtt_enabled && mqtt_command(grpflg, type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
else if (sysCfg.flag.mqtt_enabled && mqtt_command(grpflg, type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
else if (hlw_flg && hlw_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
@ -1444,10 +1490,10 @@ void send_button_power(byte key, byte device, byte state)
}
#ifdef USE_DOMOTICZ
if (!(domoticz_button(key, device, state, strlen(svalue)))) {
mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.mqtt_switch_retain : sysCfg.mqtt_button_retain);
mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain);
}
#else
mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.mqtt_switch_retain : sysCfg.mqtt_button_retain);
mqtt_publish_sec(stopic, svalue, (key) ? sysCfg.flag.mqtt_switch_retain : sysCfg.flag.mqtt_button_retain);
#endif // USE_DOMOTICZ
}
@ -1552,7 +1598,7 @@ void publish_status(uint8_t payload)
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
option = (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1]) && (!payload));
if ((!sysCfg.mqtt_enabled) && (6 == payload)) {
if ((!sysCfg.flag.mqtt_enabled) && (6 == payload)) {
payload = 99;
}
if ((!hlw_flg) && ((8 == payload) || (9 == payload))) {
@ -1561,7 +1607,7 @@ void publish_status(uint8_t payload)
if ((0 == payload) || (99 == payload)) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Status\":{\"Module\":%d, \"FriendlyName\":\"%s\", \"Topic\":\"%s\", \"ButtonTopic\":\"%s\", \"Power\":%d, \"PowerOnState\":%d, \"LedState\":%d, \"SaveData\":%d, \"SaveState\":%d, \"ButtonRetain\":%d, \"PowerRetain\":%d}}"),
sysCfg.module +1, sysCfg.friendlyname[0], sysCfg.mqtt_topic, sysCfg.button_topic, power, sysCfg.poweronstate, sysCfg.ledstate, sysCfg.savedata, sysCfg.savestate, sysCfg.mqtt_button_retain, sysCfg.mqtt_power_retain);
sysCfg.module +1, sysCfg.friendlyname[0], sysCfg.mqtt_topic, sysCfg.button_topic, power, sysCfg.poweronstate, sysCfg.ledstate, sysCfg.savedata, sysCfg.flag.savestate, sysCfg.flag.mqtt_button_retain, sysCfg.flag.mqtt_power_retain);
mqtt_publish_topic_P(option, PSTR("STATUS"), svalue);
}
@ -1596,7 +1642,7 @@ void publish_status(uint8_t payload)
mqtt_publish_topic_P(option, PSTR("STATUS5"), svalue);
}
if (((0 == payload) || (6 == payload)) && sysCfg.mqtt_enabled) {
if (((0 == payload) || (6 == payload)) && sysCfg.flag.mqtt_enabled) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMQT\":{\"Host\":\"%s\", \"Port\":%d, \"ClientMask\":\"%s\", \"Client\":\"%s\", \"User\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"),
sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, MQTTClient, sysCfg.mqtt_user, MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
mqtt_publish_topic_P(option, PSTR("STATUS6"), svalue);
@ -1687,7 +1733,7 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
#endif // USE_DS18x20
}
#ifdef USE_DHT
if (dht_type) {
if (dht_flg) {
dht_mqttPresent(svalue, ssvalue, djson);
}
#endif // USE_DHT
@ -1707,6 +1753,9 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
#endif // USE_BH1750
}
#endif // USE_I2C
if (strstr_P(svalue, PSTR("Temperature"))) {
snprintf_P(svalue, ssvalue, PSTR("%s, \"TempUnit\":\"%c\""), svalue, tempUnit());
}
snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue);
}
@ -1735,7 +1784,7 @@ void every_second()
if (syslog_timer) { // Restore syslog level
syslog_timer--;
if (!syslog_timer) {
syslog_level = (sysCfg.emulation) ? 0 : sysCfg.syslog_level;
syslog_level = (sysCfg.flag.emulation) ? 0 : sysCfg.syslog_level;
if (sysCfg.syslog_level) {
addLog_P(LOG_LEVEL_INFO, PSTR("SYSL: Syslog logging re-enabled")); // Might trigger disable again (on purpose)
}
@ -1768,7 +1817,7 @@ void every_second()
#endif // USE_DS18x20
}
#ifdef USE_DHT
if (dht_type) {
if (dht_flg) {
dht_readPrep();
}
#endif // USE_DHT
@ -1914,7 +1963,7 @@ void stateloop()
holdcount = 0;
} else {
holdcount++;
if (!sysCfg.button_restrict && ((STATES *4) == holdcount)) { // 4 seconds button hold
if (!sysCfg.flag.button_restrict && ((STATES *4) == holdcount)) { // 4 seconds button hold
snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1"));
multipress = 0;
do_cmnd(scmnd);
@ -1929,7 +1978,7 @@ void stateloop()
} else {
flag = (1 == multipress);
}
if (flag && sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) {
if (flag && sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) {
send_button_power(0, multipress, 2); // Execute command via MQTT using ButtonTopic to sync external clients
} else {
if ((1 == multipress) || (2 == multipress)) {
@ -1939,7 +1988,7 @@ void stateloop()
do_cmnd_power(multipress, 2); // Execute command internally
}
} else {
if (!sysCfg.button_restrict) {
if (!sysCfg.flag.button_restrict) {
snprintf_P(scmnd, sizeof(scmnd), commands[multipress -3]);
do_cmnd(scmnd);
}
@ -1953,7 +2002,7 @@ void stateloop()
if (pin[GPIO_KEY1 +i] < 99) {
button = digitalRead(pin[GPIO_KEY1 +i]);
if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) {
if (sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) {
if (sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.button_topic) != 0) && strcmp(sysCfg.button_topic, "0")) {
send_button_power(0, i +1, 2); // Execute commend via MQTT
} else {
do_cmnd_power(i +1, 2); // Execute command internally
@ -1989,7 +2038,7 @@ void stateloop()
}
}
if (switchflag < 3) {
if (sysCfg.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.switch_topic) != 0) && strcmp(sysCfg.switch_topic, "0")) {
if (sysCfg.flag.mqtt_enabled && mqttClient.connected() && (strlen(sysCfg.switch_topic) != 0) && strcmp(sysCfg.switch_topic, "0")) {
send_button_power(1, i +1, switchflag); // Execute commend via MQTT
} else {
do_cmnd_power(i +1, switchflag); // Execute command internally (if i < Maxdevice)
@ -2066,7 +2115,7 @@ void stateloop()
if (savedatacounter) {
savedatacounter--;
if (savedatacounter <= 0) {
if (sysCfg.savestate) {
if (sysCfg.flag.savestate) {
byte mask = 0xFF;
for (byte i = 0; i < MAX_PULSETIMERS; i++) {
if ((sysCfg.pulsetime[i] > 0) && (sysCfg.pulsetime[i] < 30)) {
@ -2091,7 +2140,7 @@ void stateloop()
CFG_Default();
restartflag = 2;
}
if (sysCfg.savestate) {
if (sysCfg.flag.savestate) {
sysCfg.power = power;
}
if (hlw_flg) {
@ -2111,7 +2160,7 @@ void stateloop()
break;
case (STATES/10)*8:
if (WL_CONNECTED == WiFi.status()) {
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
if (!mqttClient.connected()) {
if (!mqttcounter) {
mqtt_reconnect();
@ -2231,17 +2280,16 @@ void GPIO_init()
led_inverted[mpin - GPIO_LED1_INV] = 1;
mpin -= 4;
}
else if (GPIO_DHT11 == mpin) {
dht_type = mpin;
}
else if (GPIO_DHT21 == mpin) {
dht_type = mpin;
mpin--;
}
else if (GPIO_DHT22 == mpin) {
dht_type = mpin;
mpin -= 2;
else if ((mpin >= GPIO_DHT11) && (mpin <= GPIO_DHT22)) {
if (dht_setup(i, mpin)) {
dht_flg = 1;
mpin = GPIO_DHT11;
} else {
mpin = 0;
}
}
}
if (mpin) {
pin[mpin] = i;
}
}
@ -2326,7 +2374,7 @@ void GPIO_init()
}
#ifdef USE_DHT
if (dht_type) {
if (dht_flg) {
dht_init();
}
#endif // USE_DHT
@ -2389,9 +2437,9 @@ void setup()
seriallog_timer = SERIALLOG_TIMER;
seriallog_level = sysCfg.seriallog_level;
#ifndef USE_EMULATION
sysCfg.emulation = 0;
sysCfg.flag.emulation = 0;
#endif // USE_EMULATION
syslog_level = (sysCfg.emulation) ? 0 : sysCfg.syslog_level;
syslog_level = (sysCfg.flag.emulation) ? 0 : sysCfg.syslog_level;
sleep = sysCfg.sleep;
GPIO_init();
@ -2432,19 +2480,19 @@ void setup()
}
else if (2 == sysCfg.poweronstate) { // All saved state toggle
power = sysCfg.power & ((1 << Maxdevice) -1) ^ 0xFF;
if (sysCfg.savestate) {
if (sysCfg.flag.savestate) {
setRelay(power);
}
}
else if (3 == sysCfg.poweronstate) { // All saved state
power = sysCfg.power & ((1 << Maxdevice) -1);
if (sysCfg.savestate) {
if (sysCfg.flag.savestate) {
setRelay(power);
}
}
} else {
power = sysCfg.power & ((1 << Maxdevice) -1);
if (sysCfg.savestate) {
if (sysCfg.flag.savestate) {
setRelay(power);
}
}
@ -2470,7 +2518,7 @@ void loop()
#endif // USE_WEBSERVER
#ifdef USE_EMULATION
if (sysCfg.emulation) {
if (sysCfg.flag.emulation) {
pollUDP();
}
#endif // USE_EMULATION
@ -2478,7 +2526,7 @@ void loop()
if (millis() >= timerxs) {
stateloop();
}
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
mqttClient.loop();
}
if (Serial.available()){

View File

@ -475,7 +475,7 @@ void WIFI_Check(uint8_t param)
stopWebserver();
}
#ifdef USE_EMULATION
if (sysCfg.emulation) {
if (sysCfg.flag.emulation) {
UDP_Connect();
}
#endif // USE_EMULATION
@ -942,6 +942,25 @@ void rtc_init()
tickerRTC.attach(1, rtc_second);
}
/*********************************************************************************************\
* Miscellaneous
\*********************************************************************************************/
float convertTemp(float c)
{
float result = c;
if (!isnan(c) && sysCfg.flag.temperature_conversion) {
result = c * 1.8 + 32; // Fahrenheit
}
return result;
}
char tempUnit()
{
return (sysCfg.flag.temperature_conversion) ? 'F' : 'C';
}
/*********************************************************************************************\
* Syslog
\*********************************************************************************************/

View File

@ -120,11 +120,11 @@
#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON or PUSHBUTTON_INV (the wall switch state)
#define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with
#define TEMP_CONVERSION 0 // Convert temperature to (0 = Celsius or 1 = Fahrenheit)
#define TEMP_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Temperature
#define HUMIDITY_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Humidity
#define PRESSURE_RESOLUTION 1 // Maximum number of decimals (0 - 3) showing sensor Pressure
#define ENERGY_RESOLUTION 3 // Maximum number of decimals (0 - 5) showing energy usage in kWh
#define TEMP_CONVERSION 0 // [TempUnit] Return temperature in (0 = Celsius or 1 = Fahrenheit)
#define TEMP_RESOLUTION 1 // [TempRes] Maximum number of decimals (0 - 3) showing sensor Temperature
#define HUMIDITY_RESOLUTION 1 // [HumRes] Maximum number of decimals (0 - 3) showing sensor Humidity
#define PRESSURE_RESOLUTION 1 // [PressRes] Maximum number of decimals (0 - 3) showing sensor Pressure
#define ENERGY_RESOLUTION 3 // [EnergyRes] Maximum number of decimals (0 - 5) showing energy usage in kWh
// -- Sensor code selection -----------------------
#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices

View File

@ -303,7 +303,7 @@ void startWebserver(int type, IPAddress ipweb)
webServer->on("/md", handleModule);
webServer->on("/w1", handleWifi1);
webServer->on("/w0", handleWifi0);
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
webServer->on("/mq", handleMqtt);
#ifdef USE_DOMOTICZ
webServer->on("/dm", handleDomoticz);
@ -326,12 +326,12 @@ void startWebserver(int type, IPAddress ipweb)
webServer->on("/rb", handleRestart);
webServer->on("/fwlink", handleRoot); // Microsoft captive portal. Maybe not needed. Might be handled by notFound handler.
#ifdef USE_EMULATION
if (EMUL_WEMO == sysCfg.emulation) {
if (EMUL_WEMO == sysCfg.flag.emulation) {
webServer->on("/upnp/control/basicevent1", HTTP_POST, handleUPnPevent);
webServer->on("/eventservice.xml", handleUPnPservice);
webServer->on("/setup.xml", handleUPnPsetupWemo);
}
if (EMUL_HUE == sysCfg.emulation) {
if (EMUL_HUE == sysCfg.flag.emulation) {
webServer->on("/description.xml", handleUPnPsetupHue);
}
#endif // USE_EMULATION
@ -483,7 +483,7 @@ void handleAjax2()
}
#endif // USE_DS18x20
#ifdef USE_DHT
if (dht_type) {
if (dht_flg) {
tpage += dht_webPresent();
}
#endif // USE_DHT
@ -554,7 +554,7 @@ void handleConfig()
String page = FPSTR(HTTP_HEAD);
page.replace("{v}", "Configuration");
page += FPSTR(HTTP_BTN_MENU2);
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
page += FPSTR(HTTP_BTN_MENU3);
}
page += FPSTR(HTTP_BTN_MENU4);
@ -857,16 +857,16 @@ void handleOther()
page.replace("{v}", "Configure Other");
page += FPSTR(HTTP_FORM_OTHER);
page.replace("{p1}", sysCfg.web_password);
page.replace("{r1}", (sysCfg.mqtt_enabled) ? " checked" : "");
page.replace("{r1}", (sysCfg.flag.mqtt_enabled) ? " checked" : "");
page += FPSTR(HTTP_FORM_OTHER2);
page.replace("{1", "1");
page.replace("{2", FRIENDLY_NAME);
page.replace("{3", sysCfg.friendlyname[0]);
#ifdef USE_EMULATION
page += FPSTR(HTTP_FORM_OTHER3);
page.replace("{r2}", (EMUL_NONE == sysCfg.emulation) ? " checked" : "");
page.replace("{r3}", (EMUL_WEMO == sysCfg.emulation) ? " checked" : "");
page.replace("{r4}", (EMUL_HUE == sysCfg.emulation) ? " checked" : "");
page.replace("{r2}", (EMUL_NONE == sysCfg.flag.emulation) ? " checked" : "");
page.replace("{r3}", (EMUL_WEMO == sysCfg.flag.emulation) ? " checked" : "");
page.replace("{r4}", (EMUL_HUE == sysCfg.flag.emulation) ? " checked" : "");
for (int i = 1; i < Maxdevice; i++) {
page += FPSTR(HTTP_FORM_OTHER2);
page.replace("{1", String(i +1));
@ -972,16 +972,16 @@ void handleSave()
#endif // USE_DOMOTICZ
case 5:
strlcpy(sysCfg.web_password, (!strlen(webServer->arg("p1").c_str())) ? WEB_PASSWORD : (!strcmp(webServer->arg("p1").c_str(),"0")) ? "" : webServer->arg("p1").c_str(), sizeof(sysCfg.web_password));
sysCfg.mqtt_enabled = webServer->hasArg("b1");
sysCfg.flag.mqtt_enabled = webServer->hasArg("b1");
#ifdef USE_EMULATION
sysCfg.emulation = (!strlen(webServer->arg("b2").c_str())) ? 0 : atoi(webServer->arg("b2").c_str());
sysCfg.flag.emulation = (!strlen(webServer->arg("b2").c_str())) ? 0 : atoi(webServer->arg("b2").c_str());
#endif // USE_EMULATION
strlcpy(sysCfg.friendlyname[0], (!strlen(webServer->arg("a1").c_str())) ? FRIENDLY_NAME : webServer->arg("a1").c_str(), sizeof(sysCfg.friendlyname[0]));
strlcpy(sysCfg.friendlyname[1], (!strlen(webServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : webServer->arg("a2").c_str(), sizeof(sysCfg.friendlyname[1]));
strlcpy(sysCfg.friendlyname[2], (!strlen(webServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : webServer->arg("a3").c_str(), sizeof(sysCfg.friendlyname[2]));
strlcpy(sysCfg.friendlyname[3], (!strlen(webServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : webServer->arg("a4").c_str(), sizeof(sysCfg.friendlyname[3]));
snprintf_P(log, sizeof(log), PSTR("HTTP: Other MQTT Enable %s, Emulation %d, Friendly Names %s, %s, %s and %s"),
getStateText(sysCfg.mqtt_enabled), sysCfg.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]);
getStateText(sysCfg.flag.mqtt_enabled), sysCfg.flag.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]);
addLog(LOG_LEVEL_INFO, log);
break;
case 6:
@ -1190,7 +1190,7 @@ void handleUploadLoop()
#ifdef USE_EMULATION
UDP_Disconnect();
#endif // USE_EMULATION
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
mqttClient.disconnect();
}
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
@ -1320,7 +1320,7 @@ void handleCmnd()
if (message.length()) {
message += F("\n");
}
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
// [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [RESULT = {"POWER":"OFF"}]
// message += Log[counter].substring(17 + strlen(PUB_PREFIX) + strlen(sysCfg.mqtt_topic));
message += Log[counter].substring(Log[counter].lastIndexOf("/",Log[counter].indexOf("="))+1);
@ -1469,7 +1469,7 @@ void handleInfo()
page += F("<tr><th>AP MAC address</th><td>"); page += WiFi.softAPmacAddress(); page += F("</td></tr>");
}
page += F("<tr><td>&nbsp;</td></tr>");
if (sysCfg.mqtt_enabled) {
if (sysCfg.flag.mqtt_enabled) {
page += F("<tr><th>MQTT Host</th><td>"); page += sysCfg.mqtt_host; page += F("</td></tr>");
page += F("<tr><th>MQTT Port</th><td>"); page += String(sysCfg.mqtt_port); page += F("</td></tr>");
page += F("<tr><th>MQTT Client &<br/>&nbsp;Fallback Topic</th><td>"); page += MQTTClient; page += F("</td></tr>");
@ -1483,10 +1483,10 @@ void handleInfo()
page += F("<tr><th>Emulation</th><td>");
#ifdef USE_EMULATION
if (EMUL_WEMO == sysCfg.emulation) {
if (EMUL_WEMO == sysCfg.flag.emulation) {
page += F("Belkin WeMo");
}
else if (EMUL_HUE == sysCfg.emulation) {
else if (EMUL_HUE == sysCfg.flag.emulation) {
page += F("Hue Bridge");
}
else {
@ -1556,7 +1556,7 @@ void handleNotFound()
#ifdef USE_EMULATION
String path = webServer->uri();
if ((EMUL_HUE == sysCfg.emulation) && (path.startsWith("/api"))) {
if ((EMUL_HUE == sysCfg.flag.emulation) && (path.startsWith("/api"))) {
handle_hue_api(&path);
} else
#endif // USE_EMULATION

View File

@ -111,13 +111,10 @@ void sc_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
char stemp1[10];
char stemp2[10];
float t = sc_value[1];
if (TEMP_CONVERSION) {
t = sc_convertCtoF(t);
}
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
float t = convertTemp(sc_value[1]);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
float h = sc_value[0];
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2);
// snprintf_P(svalue, ssvalue, PSTR("%s, \"SC\":{\"Temperature\":%s, \"Humidity\":%s, \"Light\":%d, \"Noise\":%d, \"AirQuality\":%d}"),
snprintf_P(svalue, ssvalue, PSTR("%s, \"Temperature\":%s, \"Humidity\":%s, \"Light\":%d, \"Noise\":%d, \"AirQuality\":%d"),
svalue, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]);
@ -139,15 +136,12 @@ String sc_webPresent()
char sensor[80];
char scstype[] = "";
float t = sc_value[1];
if (TEMP_CONVERSION) {
t = sc_convertCtoF(t);
}
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
float t = convertTemp(sc_value[1]);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, tempUnit());
page += sensor;
float h = sc_value[0];
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp);
dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, scstype, stemp);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_LIGHT, scstype, sc_value[2]);

View File

@ -214,10 +214,10 @@ void pollUDP()
String request = packetBuffer;
// addLog_P(LOG_LEVEL_DEBUG_MORE, packetBuffer);
if (request.indexOf("M-SEARCH") >= 0) {
if ((EMUL_WEMO == sysCfg.emulation) &&(request.indexOf("urn:Belkin:device:**") > 0)) {
if ((EMUL_WEMO == sysCfg.flag.emulation) &&(request.indexOf("urn:Belkin:device:**") > 0)) {
wemo_respondToMSearch();
}
else if ((EMUL_HUE == sysCfg.emulation) && ((request.indexOf("ST: urn:schemas-upnp-org:device:basic:1") > 0) || (request.indexOf("ST: upnp:rootdevice") > 0) || (request.indexOf("ST: ssdp:all") > 0))) {
else if ((EMUL_HUE == sysCfg.flag.emulation) && ((request.indexOf("ST: urn:schemas-upnp-org:device:basic:1") > 0) || (request.indexOf("ST: upnp:rootdevice") > 0) || (request.indexOf("ST: ssdp:all") > 0))) {
hue_respondToMSearch();
}
}

View File

@ -351,12 +351,7 @@ double bme280_readHumidity(void)
* BMP
\*********************************************************************************************/
double bmp_convertCtoF(double c)
{
return c * 1.8 + 32;
}
double bmp_readTemperature(bool S)
double bmp_readTemperature(void)
{
double t = NAN;
@ -369,9 +364,7 @@ double bmp_readTemperature(bool S)
t = bmp280_readTemperature();
}
if (!isnan(t)) {
if (S) {
t = bmp_convertCtoF(t);
}
t = convertTemp(t);
return t;
}
return 0;
@ -453,12 +446,12 @@ void bmp_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
char stemp2[10];
char stemp3[10];
double t = bmp_readTemperature(TEMP_CONVERSION);
double t = bmp_readTemperature();
double p = bmp_readPressure();
double h = bmp_readHumidity();
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
dtostrf(p, 1, PRESSURE_RESOLUTION &3, stemp2);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp3);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
dtostrf(p, 1, sysCfg.flag.pressure_resolution, stemp2);
dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp3);
if (!strcmp(bmpstype,"BME280")) {
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s, \"Pressure\":%s}"),
svalue, bmpstype, stemp1, stemp3, stemp2);
@ -480,18 +473,18 @@ String bmp_webPresent()
char stemp[10];
char sensor[80];
double t_bmp = bmp_readTemperature(TEMP_CONVERSION);
double t_bmp = bmp_readTemperature();
double p_bmp = bmp_readPressure();
double h_bmp = bmp_readHumidity();
dtostrf(t_bmp, 1, TEMP_RESOLUTION &3, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmpstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
dtostrf(t_bmp, 1, sysCfg.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmpstype, stemp, tempUnit());
page += sensor;
if (!strcmp(bmpstype,"BME280")) {
dtostrf(h_bmp, 1, HUMIDITY_RESOLUTION &3, stemp);
dtostrf(h_bmp, 1, sysCfg.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, bmpstype, stemp);
page += sensor;
}
dtostrf(p_bmp, 1, PRESSURE_RESOLUTION &3, stemp);
dtostrf(p_bmp, 1, sysCfg.flag.pressure_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSURE, bmpstype, stemp);
page += sensor;
}

View File

@ -32,71 +32,80 @@ POSSIBILITY OF SUCH DAMAGE.
* Source: Adafruit Industries https://github.com/adafruit/DHT-sensor-library
\*********************************************************************************************/
#define MIN_INTERVAL 2000
#define DHT_MAX_SENSORS 3
#define MIN_INTERVAL 2000
uint8_t data[5];
char dhtstype[7];
uint32_t _lastreadtime;
uint32_t _maxcycles;
bool _lastresult;
float mt;
float mh = 0;
uint32_t dht_maxcycles;
uint8_t dht_data[5];
byte dht_sensors = 0;
struct DHTSTRUCT {
byte pin;
byte type;
char stype[10];
uint32_t lastreadtime;
bool lastresult;
float t;
float h = 0;
} dht[DHT_MAX_SENSORS];
void dht_readPrep()
{
digitalWrite(pin[GPIO_DHT11], HIGH);
for (byte i = 0; i < dht_sensors; i++) {
digitalWrite(dht[i].pin, HIGH);
}
}
uint32_t dht_expectPulse(bool level)
uint32_t dht_expectPulse(byte sensor, bool level)
{
uint32_t count = 0;
while (digitalRead(pin[GPIO_DHT11]) == level) {
if (count++ >= _maxcycles) {
while (digitalRead(dht[sensor].pin) == level) {
if (count++ >= dht_maxcycles) {
return 0;
}
}
return count;
}
boolean dht_read()
boolean dht_read(byte sensor)
{
char log[LOGSZ];
uint32_t cycles[80];
uint32_t currenttime = millis();
if ((currenttime - _lastreadtime) < 2000) {
return _lastresult;
if ((currenttime - dht[sensor].lastreadtime) < 2000) {
return dht[sensor].lastresult;
}
_lastreadtime = currenttime;
dht[sensor].lastreadtime = currenttime;
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
dht_data[0] = dht_data[1] = dht_data[2] = dht_data[3] = dht_data[4] = 0;
// digitalWrite(pin[GPIO_DHT11], HIGH);
// digitalWrite(dht[sensor].pin, HIGH);
// delay(250);
pinMode(pin[GPIO_DHT11], OUTPUT);
digitalWrite(pin[GPIO_DHT11], LOW);
pinMode(dht[sensor].pin, OUTPUT);
digitalWrite(dht[sensor].pin, LOW);
delay(20);
noInterrupts();
digitalWrite(pin[GPIO_DHT11], HIGH);
digitalWrite(dht[sensor].pin, HIGH);
delayMicroseconds(40);
pinMode(pin[GPIO_DHT11], INPUT_PULLUP);
pinMode(dht[sensor].pin, INPUT_PULLUP);
delayMicroseconds(10);
if (0 == dht_expectPulse(LOW)) {
if (0 == dht_expectPulse(sensor, LOW)) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for start signal low pulse"));
_lastresult = false;
return _lastresult;
dht[sensor].lastresult = false;
return dht[sensor].lastresult;
}
if (0 == dht_expectPulse(HIGH)) {
if (0 == dht_expectPulse(sensor, HIGH)) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for start signal high pulse"));
_lastresult = false;
return _lastresult;
dht[sensor].lastresult = false;
return dht[sensor].lastresult;
}
for (int i = 0; i < 80; i += 2) {
cycles[i] = dht_expectPulse(LOW);
cycles[i+1] = dht_expectPulse(HIGH);
cycles[i] = dht_expectPulse(sensor, LOW);
cycles[i+1] = dht_expectPulse(sensor, HIGH);
}
interrupts();
@ -105,101 +114,105 @@ boolean dht_read()
uint32_t highCycles = cycles[2*i+1];
if ((0 == lowCycles) || (0 == highCycles)) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for pulse"));
_lastresult = false;
return _lastresult;
dht[sensor].lastresult = false;
return dht[sensor].lastresult;
}
data[i/8] <<= 1;
dht_data[i/8] <<= 1;
if (highCycles > lowCycles) {
data[i/8] |= 1;
dht_data[i/8] |= 1;
}
}
snprintf_P(log, sizeof(log), PSTR("DHT: Received %02X, %02X, %02X, %02X, %02X =? %02X"),
data[0], data[1], data[2], data[3], data[4], (data[0] + data[1] + data[2] + data[3]) & 0xFF);
dht_data[0], dht_data[1], dht_data[2], dht_data[3], dht_data[4], (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF);
addLog(LOG_LEVEL_DEBUG, log);
if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
_lastresult = true;
return _lastresult;
if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) {
dht[sensor].lastresult = true;
} else {
addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Checksum failure"));
_lastresult = false;
return _lastresult;
dht[sensor].lastresult = false;
}
return dht[sensor].lastresult;
}
float dht_convertCtoF(float c)
boolean dht_readTempHum(byte sensor, float &t, float &h)
{
return c * 1.8 + 32;
}
boolean dht_readTempHum(bool S, float &t, float &h)
{
if (!mh) {
if (!dht[sensor].h) {
t = NAN;
h = NAN;
} else {
t = mt;
h = mh;
t = dht[sensor].t;
h = dht[sensor].h;
}
if (dht_read()) {
switch (dht_type) {
if (dht_read(sensor)) {
switch (dht[sensor].type) {
case GPIO_DHT11:
h = data[0];
t = data[2];
if (S) {
t = dht_convertCtoF(t);
}
h = dht_data[0];
t = convertTemp(dht_data[2]);
break;
case GPIO_DHT22:
case GPIO_DHT21:
h = data[0];
h = dht_data[0];
h *= 256;
h += data[1];
h += dht_data[1];
h *= 0.1;
t = data[2] & 0x7F;
t = dht_data[2] & 0x7F;
t *= 256;
t += data[3];
t += dht_data[3];
t *= 0.1;
if (data[2] & 0x80) {
if (dht_data[2] & 0x80) {
t *= -1;
}
if (S) {
t = dht_convertCtoF(t);
}
t = convertTemp(t);
break;
}
if (!isnan(t)) {
mt = t;
dht[sensor].t = t;
}
if (!isnan(h)) {
mh = h;
dht[sensor].h = h;
}
}
return (!isnan(t) && !isnan(h));
}
boolean dht_setup(byte pin, byte type)
{
boolean success = false;
if (dht_sensors < DHT_MAX_SENSORS) {
dht[dht_sensors].pin = pin;
dht[dht_sensors].type = type;
dht_sensors++;
success = true;
}
return success;
}
void dht_init()
{
char log[LOGSZ];
_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for
// reading pulses from DHT sensor.
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");
dht_maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for reading pulses from DHT sensor.
for (byte i = 0; i < dht_sensors; i++) {
pinMode(dht[i].pin, INPUT_PULLUP);
dht[i].lastreadtime = -MIN_INTERVAL;
switch (dht[i].type) {
case GPIO_DHT11:
snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("DHT11-%02d"), dht[i].pin);
break;
case GPIO_DHT21:
snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("AM2301-%02d"), dht[i].pin);
break;
case GPIO_DHT22:
snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("DHT22-%02d"), dht[i].pin);
}
}
snprintf_P(log, sizeof(log), PSTR("DHT: Max clock cycles %d"), _maxcycles);
snprintf_P(log, sizeof(log), PSTR("DHT: Max clock cycles %d"), dht_maxcycles);
addLog(LOG_LEVEL_DEBUG, log);
}
@ -214,16 +227,22 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
float t;
float h;
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, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
// svalue, dhtstype, stemp1, stemp2);
snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dhtstype, stemp1, stemp2);
*djson = 1;
byte dsxflg = 0;
for (byte i = 0; i < dht_sensors; i++) {
if (dht_readTempHum(i, t, h)) { // Read temperature
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2);
// snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
// svalue, dhtstype, stemp1, stemp2);
snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dht[i].stype, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
domoticz_sensor2(stemp1, stemp2);
if (!dsxflg) {
domoticz_sensor2(stemp1, stemp2);
dsxflg++;
}
#endif // USE_DOMOTICZ
}
}
}
@ -231,20 +250,20 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
String dht_webPresent()
{
String page = "";
char stemp[10];
char sensor[80];
float t;
float h;
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature as Celsius (the default)
char stemp[10];
char sensor[80];
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dhtstype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
page += sensor;
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dhtstype, stemp);
page += sensor;
for (byte i = 0; i < dht_sensors; i++) {
if (dht_readTempHum(i, t, h)) {
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dht[i].stype, stemp, tempUnit());
page += sensor;
dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dht[i].stype, stemp);
page += sensor;
}
}
return page;
}

View File

@ -129,12 +129,7 @@ void dsb_readTempPrep()
dsb_write(0x44); // Start conversion
}
float dsb_convertCtoF(float c)
{
return c * 1.8 + 32;
}
boolean dsb_readTemp(bool S, float &t)
boolean dsb_readTemp(float &t)
{
int16_t DSTemp;
byte msb, lsb, crc, sign = 1;
@ -178,10 +173,7 @@ boolean dsb_readTemp(bool S, float &t)
DSTemp = (~DSTemp) +1;
sign = -1;
}
t = (float)sign * DSTemp * 0.0625;
if(S) {
t = dsb_convertCtoF(t);
}
t = convertTemp((float)sign * DSTemp * 0.0625);
}
if (!isnan(t)) dsb_mt = t;
return !isnan(t);
@ -196,8 +188,8 @@ void dsb_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
char stemp1[10];
float t;
if (dsb_readTemp(TEMP_CONVERSION, t)) { // Check if read failed
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
if (dsb_readTemp(t)) { // Check if read failed
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"Temperature\":%s}"), svalue, stemp1);
*djson = 1;
#ifdef USE_DOMOTICZ
@ -213,12 +205,12 @@ String dsb_webPresent()
String page = "";
float st;
if (dsb_readTemp(TEMP_CONVERSION, st)) { // Check if read failed
if (dsb_readTemp(st)) { // Check if read failed
char stemp[10];
char sensor[80];
dtostrf(st, 1, TEMP_RESOLUTION &3, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, (TEMP_CONVERSION) ? 'F' : 'C');
dtostrf(st, 1, sysCfg.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, tempUnit());
page += sensor;
}
dsb_readTempPrep();

View File

@ -107,12 +107,7 @@ void ds18x20_convert()
// delay(750); // 750ms should be enough for 12bit conv
}
float ds18x20_convertCtoF(float c)
{
return c * 1.8 + 32;
}
boolean ds18x20_read(uint8_t sensor, bool S, float &t)
boolean ds18x20_read(uint8_t sensor, float &t)
{
byte data[12];
int8_t sign = 1;
@ -155,10 +150,7 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t)
} else {
temp9 = (data[0] >> 1) * sign;
}
t = (temp9 - 0.25) + ((16.0 - data[6]) / 16.0);
if(S) {
t = ds18x20_convertCtoF(t);
}
t = convertTemp((temp9 - 0.25) + ((16.0 - data[6]) / 16.0));
break;
case DS18B20_CHIPID: // DS18B20
case MAX31850_CHIPID: // MAX31850
@ -167,10 +159,7 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t)
temp12 = (~temp12) +1;
sign = -1;
}
t = sign * temp12 * 0.0625;
if(S) {
t = ds18x20_convertCtoF(t);
}
t = convertTemp(sign * temp12 * 0.0625);
break;
}
}
@ -205,9 +194,9 @@ 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
if (ds18x20_read(i, t)) { // Check if read failed
ds18x20_type(i);
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp2);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp2);
if (!dsxflg) {
snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18x20\":{"), svalue);
*djson = 1;
@ -237,11 +226,11 @@ String ds18x20_webPresent()
float t;
for (byte i = 0; i < ds18x20_sensors(); i++) {
if (ds18x20_read(i, TEMP_CONVERSION, t)) { // Check if read failed
if (ds18x20_read(i, t)) { // Check if read failed
ds18x20_type(i);
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp);
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');
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, tempUnit());
page += sensor;
}
}

View File

@ -375,7 +375,7 @@ void hlw_margin_chk()
} else {
hlw_mplh_counter--;
if (!hlw_mplh_counter) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pw, (sysCfg.value_units) ? " W" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pw, (sysCfg.flag.value_units) ? " W" : "");
mqtt_publish_topic_P(0, PSTR("WARNING"), svalue);
do_cmnd_power(1, 0);
if (!hlw_mplr_counter) {
@ -421,7 +421,7 @@ void hlw_margin_chk()
else if ((1 == hlw_mkwh_state) && (uped >= sysCfg.hlw_mkwh)) {
hlw_mkwh_state = 2;
dtostrf(ped, 1, 3, svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.value_units) ? " kWh" : "");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " kWh" : "");
mqtt_publish_topic_P(0, PSTR("WARNING"), svalue);
do_cmnd_power(1, 0);
}
@ -441,105 +441,105 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_pmin = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.value_units) ? " W" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " W" : "");
}
else if (!strcmp_P(type,PSTR("POWERHIGH"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_pmax = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.value_units) ? " W" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " W" : "");
}
else if (!strcmp_P(type,PSTR("VOLTAGELOW"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 501)) {
sysCfg.hlw_umin = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.value_units) ? " V" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " V" : "");
}
else if (!strcmp_P(type,PSTR("VOLTAGEHIGH"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 501)) {
sysCfg.hlw_umax = payload;
}
snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.value_units) ? " V" : "");
snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " V" : "");
}
else if (!strcmp_P(type,PSTR("CURRENTLOW"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 16001)) {
sysCfg.hlw_imin = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.value_units) ? " mA" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " mA" : "");
}
else if (!strcmp_P(type,PSTR("CURRENTHIGH"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 16001)) {
sysCfg.hlw_imax = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.value_units) ? " mA" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " mA" : "");
}
else if (!strcmp_P(type,PSTR("HLWPCAL"))) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_pcal = (payload > 9999) ? payload : HLW_PREF_PULSE; // 12530
}
snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.value_units) ? " uS" : "");
snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " uS" : "");
}
else if (!strcmp_P(type,PSTR("HLWUCAL"))) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_ucal = (payload > 999) ? payload : HLW_UREF_PULSE; // 1950
}
snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.value_units) ? " uS" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " uS" : "");
}
else if (!strcmp_P(type,PSTR("HLWICAL"))) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_ical = (payload > 2499) ? payload : HLW_IREF_PULSE; // 3500
}
snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.value_units) ? " uS" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " uS" : "");
}
#if FEATURE_POWER_LIMIT
else if (!strcmp_P(type,PSTR("MAXPOWER"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mpl = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.value_units) ? " W" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " W" : "");
}
else if (!strcmp_P(type,PSTR("MAXPOWERHOLD"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mplh = (1 == payload) ? MAX_POWER_HOLD : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.value_units) ? " Sec" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " Sec" : "");
}
else if (!strcmp_P(type,PSTR("MAXPOWERWINDOW"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mplw = (1 == payload) ? MAX_POWER_WINDOW : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.value_units) ? " Sec" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " Sec" : "");
}
else if (!strcmp_P(type,PSTR("SAFEPOWER"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mspl = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.value_units) ? " W" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " W" : "");
}
else if (!strcmp_P(type,PSTR("SAFEPOWERHOLD"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_msplh = (1 == payload) ? SAFE_POWER_HOLD : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.value_units) ? " Sec" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " Sec" : "");
}
else if (!strcmp_P(type,PSTR("SAFEPOWERWINDOW"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 1440)) {
sysCfg.hlw_msplw = (1 == payload) ? SAFE_POWER_WINDOW : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.value_units) ? " Min" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " Min" : "");
}
else if (!strcmp_P(type,PSTR("MAXENERGY"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mkwh = payload;
hlw_mkwh_state = 3;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.value_units) ? " Wh" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " Wh" : "");
}
else if (!strcmp_P(type,PSTR("MAXENERGYSTART"))) {
if ((data_len > 0) && (payload >= 0) && (payload < 24)) {
sysCfg.hlw_mkwhs = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.value_units) ? " Hr" : "");
snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " Hr" : "");
}
#endif // FEATURE_POWER_LIMIT
else {
@ -567,8 +567,8 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)
uint16_t pu;
hlw_readEnergy(option, ped, pe, pw, pu, pi, pc);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, ENERGY_RESOLUTION &7, stemp0);
dtostrf(ped, 1, ENERGY_RESOLUTION &7, stemp1);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp0);
dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp1);
dtostrf(pc, 1, 2, stemp2);
dtostrf(pi, 1, 3, stemp3);
snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%d"), pe);
@ -625,8 +625,8 @@ String hlw_webPresent()
dtostrf(pi, 1, 3, stemp);
dtostrf(pc, 1, 2, stemp2);
dtostrf(ped, 1, ENERGY_RESOLUTION &7, stemp3);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, ENERGY_RESOLUTION &7, stemp4);
dtostrf(ped, 1, sysCfg.flag.energy_resolution, stemp3);
dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, stemp4);
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, pu, stemp, pw, stemp2, stemp3, stemp4);
page += sensor;
return page;

View File

@ -138,11 +138,6 @@ boolean htu21_init()
return true;
}
float htu21_convertCtoF(float c)
{
return c * 1.8 + 32;
}
float htu21_readHumidity(void)
{
uint8_t checksum = 0;
@ -179,7 +174,7 @@ float htu21_readHumidity(void)
return humidity;
}
float htu21_readTemperature(bool S)
float htu21_readTemperature()
{
uint8_t checksum=0;
uint16_t sensorval=0;
@ -202,10 +197,7 @@ float htu21_readTemperature(bool S)
return 0.0; // Checksum mismatch
}
t = (0.002681 * (float)sensorval - 46.85);
if(S) {
t = htu21_convertCtoF(t);
}
t = convertTemp(0.002681 * (float)sensorval - 46.85);
return t;
}
@ -279,11 +271,11 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
char stemp1[10];
char stemp2[10];
float t = htu21_readTemperature(TEMP_CONVERSION);
float t = htu21_readTemperature();
float h = htu21_readHumidity();
h = htu21_compensatedHumidity(h, t);
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2);
snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, htustype, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
@ -299,13 +291,13 @@ String htu_webPresent()
char stemp[10];
char sensor[80];
float t_htu21 = htu21_readTemperature(TEMP_CONVERSION);
float t_htu21 = htu21_readTemperature();
float h_htu21 = htu21_readHumidity();
h_htu21 = htu21_compensatedHumidity(h_htu21, t_htu21);
dtostrf(t_htu21, 1, TEMP_RESOLUTION &3, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htustype, stemp, (TEMP_CONVERSION) ? 'F' : 'C');
dtostrf(t_htu21, 1, sysCfg.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htustype, stemp, tempUnit());
page += sensor;
dtostrf(h_htu21, 1, HUMIDITY_RESOLUTION &3, stemp);
dtostrf(h_htu21, 1, sysCfg.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, htustype, stemp);
page += sensor;
}

View File

@ -161,9 +161,7 @@ boolean sht_readTempHum(float &t, float &h)
const float t2 = 0.00008;
rhLinear = c1 + c2 * humRaw + c3 * humRaw * humRaw;
h = (t - 25) * (t1 + t2 * humRaw) + rhLinear;
if (!isnan(t) && TEMP_CONVERSION) {
t = t * 1.8 + 32;
}
t = convertTemp(t);
return (!isnan(t) && !isnan(h));
}
@ -173,8 +171,8 @@ boolean sht_readCharTempHum(char* temp, char* hum)
float h;
boolean success = sht_readTempHum(t, h);
dtostrf(t, 1, TEMP_RESOLUTION &3, temp);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, hum);
dtostrf(t, 1, sysCfg.flag.temperature_resolution, temp);
dtostrf(h, 1, sysCfg.flag.humidity_resolution, hum);
return success;
}
@ -231,7 +229,7 @@ String sht_webPresent()
if (sht_readCharTempHum(stemp, shum)) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, (TEMP_CONVERSION) ? 'F' : 'C');
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, tempUnit());
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, "SHT1X", shum);
page += sensor;