4.0.6 20170316
* Fix to better find device by Wifi hostname
* Fix compile error when some I2C devices are disabled
* Add (experimental) support for SHT1X emulating I2C (#97)
* Add ADC to ElectroDragon (#203)
* Add support for Sonoff Dev (#206)
This commit is contained in:
arendst 2017-03-16 16:23:11 +01:00
parent 7aebdbbacf
commit c4cdd4459c
9 changed files with 266 additions and 29 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota ## 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. 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 **4.0.5** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information. Current version is **4.0.6** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic. - 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```. - Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
@ -24,6 +24,7 @@ The following devices are supported:
- [iTead Slampher](http://sonoff.itead.cc/en/products/residential/slampher-rf) - [iTead Slampher](http://sonoff.itead.cc/en/products/residential/slampher-rf)
- [iTead Sonoff Touch](http://sonoff.itead.cc/en/products/residential/sonoff-touch) - [iTead Sonoff Touch](http://sonoff.itead.cc/en/products/residential/sonoff-touch)
- [iTead Sonoff Led](http://sonoff.itead.cc/en/products/appliances/sonoff-led) - [iTead Sonoff Led](http://sonoff.itead.cc/en/products/appliances/sonoff-led)
- [iTead Sonoff Dev](https://www.itead.cc/sonoff-dev.html)
- [iTead 1 Channel Switch 5V / 12V](https://www.itead.cc/smart-home/inching-self-locking-wifi-wireless-switch.html) - [iTead 1 Channel Switch 5V / 12V](https://www.itead.cc/smart-home/inching-self-locking-wifi-wireless-switch.html)
- [iTead Motor Clockwise/Anticlockwise](https://www.itead.cc/smart-home/motor-reversing-wifi-wireless-switch.html) - [iTead Motor Clockwise/Anticlockwise](https://www.itead.cc/smart-home/motor-reversing-wifi-wireless-switch.html)
- [Electrodragon IoT Relay Board](http://www.electrodragon.com/product/wifi-iot-relay-board-based-esp8266/) - [Electrodragon IoT Relay Board](http://www.electrodragon.com/product/wifi-iot-relay-board-based-esp8266/)

Binary file not shown.

View File

@ -1,4 +1,11 @@
/* 4.0.5 20170314 /* 4.0.6 20170316
* Fix to better find device by Wifi hostname
* Fix compile error when some I2C devices are disabled
* Add (experimental) support for SHT1X emulating I2C (#97)
* Add ADC to ElectroDragon (#203)
* Add support for Sonoff Dev (#206)
*
* 4.0.5 20170314
* Add command Status 11 to show power status with Vcc if define USE_ADC_VCC is enabled (default) * Add command Status 11 to show power status with Vcc if define USE_ADC_VCC is enabled (default)
* Add ADC input to Sonoff SV and Wemos D1 mini - Needs recompile with define USE_ADC_VCC disabled (#137) * Add ADC input to Sonoff SV and Wemos D1 mini - Needs recompile with define USE_ADC_VCC disabled (#137)
* Add MQTT host:port to timeout message (#199) * Add MQTT host:port to timeout message (#199)

View File

@ -12,9 +12,9 @@
//#define ALLOW_MIGRATE_TO_V3 //#define ALLOW_MIGRATE_TO_V3
#ifdef ALLOW_MIGRATE_TO_V3 #ifdef ALLOW_MIGRATE_TO_V3
#define VERSION 0x03091C00 // 3.9.28 #define VERSION 0x03091D00 // 3.9.29
#else #else
#define VERSION 0x04000500 // 4.0.5 #define VERSION 0x04000600 // 4.0.6
#endif // ALLOW_MIGRATE_TO_V3 #endif // ALLOW_MIGRATE_TO_V3
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
@ -149,7 +149,7 @@ enum butt_t {PRESSED, NOT_PRESSED};
#error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 427" #error "MQTT_MAX_PACKET_SIZE is too small in libraries/PubSubClient/src/PubSubClient.h, increase it to at least 427"
#endif #endif
#include <Ticker.h> // RTC #include <Ticker.h> // RTC, HLW8012, OSWatch
#include <ESP8266WiFi.h> // MQTT, Ota, WifiManager #include <ESP8266WiFi.h> // MQTT, Ota, WifiManager
#include <ESP8266HTTPClient.h> // MQTT, Ota #include <ESP8266HTTPClient.h> // MQTT, Ota
#include <ESP8266httpUpdate.h> // Ota #include <ESP8266httpUpdate.h> // Ota
@ -1528,6 +1528,9 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
#endif // USE_DHT #endif // USE_DHT
#ifdef USE_I2C #ifdef USE_I2C
if (i2c_flg) { if (i2c_flg) {
#ifdef USE_SHT
sht_mqttPresent(svalue, ssvalue, djson);
#endif // USE_SHT
#ifdef USE_HTU #ifdef USE_HTU
htu_mqttPresent(svalue, ssvalue, djson); htu_mqttPresent(svalue, ssvalue, djson);
#endif // USE_HTU #endif // USE_HTU
@ -1544,13 +1547,6 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
/********************************************************************************************/ /********************************************************************************************/
void every_second_cb()
{
// 1 second rtc interrupt routine
// Keep this code small (every_second is to large - it'll trip exception)
}
void every_second() void every_second()
{ {
char svalue[MESSZ]; char svalue[MESSZ];
@ -1605,6 +1601,9 @@ void every_second()
#endif // USE_DHT #endif // USE_DHT
#ifdef USE_I2C #ifdef USE_I2C
if (i2c_flg) { if (i2c_flg) {
#ifdef USE_SHT
sht_detect();
#endif // USE_SHT
#ifdef USE_HTU #ifdef USE_HTU
htu_detect(); htu_detect();
#endif // USE_HTU #endif // USE_HTU
@ -2053,7 +2052,7 @@ void GPIO_init()
#ifdef USE_I2C #ifdef USE_I2C
i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99)); i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99));
if (i2c_flg) Wire.begin(pin[GPIO_I2C_SDA],pin[GPIO_I2C_SCL]); if (i2c_flg) Wire.begin(pin[GPIO_I2C_SDA], pin[GPIO_I2C_SCL]);
#endif // USE_I2C #endif // USE_I2C
#ifdef USE_WS2812 #ifdef USE_WS2812
@ -2123,7 +2122,7 @@ void setup()
} else { } else {
snprintf_P(Hostname, sizeof(Hostname)-1, sysCfg.hostname); snprintf_P(Hostname, sizeof(Hostname)-1, sysCfg.hostname);
} }
WIFI_Connect(Hostname); WIFI_Connect();
getClient(MQTTClient, sysCfg.mqtt_client, sizeof(MQTTClient)); getClient(MQTTClient, sysCfg.mqtt_client, sizeof(MQTTClient));
@ -2151,7 +2150,7 @@ void setup()
} }
blink_powersave = power; blink_powersave = power;
rtc_init(every_second_cb); rtc_init();
snprintf_P(log, sizeof(log), PSTR("APP: Project %s %s (Topic %s, Fallback %s, GroupTopic %s) Version %s"), snprintf_P(log, sizeof(log), PSTR("APP: Project %s %s (Topic %s, Fallback %s, GroupTopic %s) Version %s"),
PROJECT, sysCfg.friendlyname[0], sysCfg.mqtt_topic, MQTTClient, sysCfg.mqtt_grptopic, Version); PROJECT, sysCfg.friendlyname[0], sysCfg.mqtt_topic, MQTTClient, sysCfg.mqtt_grptopic, Version);

View File

@ -114,6 +114,7 @@ enum module_t {
EXS_RELAY, EXS_RELAY,
WION, WION,
WEMOS, WEMOS,
SONOFF_DEV,
MAXMODULE }; MAXMODULE };
/********************************************************************************************/ /********************************************************************************************/
@ -308,7 +309,7 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
GPIO_USER, // GPIO14 Optional sensor GPIO_USER, // GPIO14 Optional sensor
GPIO_USER, // GPIO15 Optional sensor GPIO_USER, // GPIO15 Optional sensor
GPIO_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off) GPIO_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off)
0 GPIO_ADC0 // ADC0 A0 Analog input
}, },
{ "EXS Relay", // Latching relay https://ex-store.de/ESP8266-WiFi-Relay-V31 (ESP8266) { "EXS Relay", // Latching relay https://ex-store.de/ESP8266-WiFi-Relay-V31 (ESP8266)
// Module Pin 1 VCC 3V3, Module Pin 6 GND // Module Pin 1 VCC 3V3, Module Pin 6 GND
@ -352,6 +353,21 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
GPIO_USER, // GPIO15 D8 GPIO_USER, // GPIO15 D8
GPIO_USER, // GPIO16 D0 Wemos Wake GPIO_USER, // GPIO16 D0 Wemos Wake
GPIO_ADC0 // ADC0 A0 Analog input GPIO_ADC0 // ADC0 A0 Analog input
},
{ "Sonoff Dev", // Sonoff Dev (ESP8266)
GPIO_KEY1, // GPIO00 E-FW Button
GPIO_USER, // GPIO01 TX Serial RXD and Optional sensor
0, // GPIO02
GPIO_USER, // GPIO03 RX Serial TXD and Optional sensor
GPIO_USER, // GPIO04 Optional sensor
GPIO_USER, // GPIO05 Optional sensor
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_USER, // GPIO12
GPIO_LED1_INV, // GPIO13 BLUE LED
GPIO_USER, // GPIO14 Optional sensor
0, // GPIO15
0, // GPIO16
GPIO_ADC0 // ADC0 A0 Analog input
} }
}; };

View File

@ -288,6 +288,7 @@ void WIFI_begin(uint8_t flag)
#ifdef USE_STATIC_IP_ADDRESS #ifdef USE_STATIC_IP_ADDRESS
WiFi.config(ipadd, ipgat, ipsub, ipdns); // Set static IP WiFi.config(ipadd, ipgat, ipsub, ipdns); // Set static IP
#endif // USE_STATIC_IP_ADDRESS #endif // USE_STATIC_IP_ADDRESS
WiFi.hostname(Hostname);
WiFi.begin(sysCfg.sta_ssid[sysCfg.sta_active], sysCfg.sta_pwd[sysCfg.sta_active]); WiFi.begin(sysCfg.sta_ssid[sysCfg.sta_active], sysCfg.sta_pwd[sysCfg.sta_active]);
snprintf_P(log, sizeof(log), PSTR("Wifi: Connecting to AP%d %s in mode 11%c as %s..."), snprintf_P(log, sizeof(log), PSTR("Wifi: Connecting to AP%d %s in mode 11%c as %s..."),
sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], PhyMode[WiFi.getPhyMode() & 0x3], Hostname); sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], PhyMode[WiFi.getPhyMode() & 0x3], Hostname);
@ -417,10 +418,9 @@ int WIFI_State()
return state; return state;
} }
void WIFI_Connect(char *Hostname) void WIFI_Connect()
{ {
WiFi.persistent(false); // Solve possible wifi init errors WiFi.persistent(false); // Solve possible wifi init errors
WiFi.hostname(Hostname);
_wifistatus = 0; _wifistatus = 0;
_wifiretry = WIFI_RETRY_SEC; _wifiretry = WIFI_RETRY_SEC;
_wificounter = 1; _wificounter = 1;
@ -591,8 +591,6 @@ static const char monthNames[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
uint32_t utctime = 0, loctime = 0, dsttime = 0, stdtime = 0, ntptime = 0, midnight = 1451602800; uint32_t utctime = 0, loctime = 0, dsttime = 0, stdtime = 0, ntptime = 0, midnight = 1451602800;
rtcCallback rtcCb = NULL;
String getBuildDateTime() String getBuildDateTime()
{ {
// "2017-03-07T11:08:02" // "2017-03-07T11:08:02"
@ -821,21 +819,13 @@ void rtc_second()
midnight = loctime; midnight = loctime;
} }
rtcTime.Year += 1970; rtcTime.Year += 1970;
if (rtcCb) rtcCb();
} }
void rtc_init(rtcCallback cb) void rtc_init()
{ {
rtcCb = cb;
// sntp_setservername(0, (char*)NTP_SERVER1);
// sntp_setservername(1, (char*)NTP_SERVER2);
// sntp_setservername(2, (char*)NTP_SERVER3);
sntp_setservername(0, sysCfg.ntp_server[0]); sntp_setservername(0, sysCfg.ntp_server[0]);
sntp_setservername(1, sysCfg.ntp_server[1]); sntp_setservername(1, sysCfg.ntp_server[1]);
sntp_setservername(2, sysCfg.ntp_server[2]); sntp_setservername(2, sysCfg.ntp_server[2]);
sntp_stop(); sntp_stop();
sntp_set_timezone(0); // UTC time sntp_set_timezone(0); // UTC time
sntp_init(); sntp_init();

View File

@ -134,6 +134,7 @@
#define USE_BH1750 // Add I2C code for BH1750 sensor #define USE_BH1750 // Add I2C code for BH1750 sensor
#define USE_BMP // Add I2C code for BMP/BME280 sensor #define USE_BMP // Add I2C code for BMP/BME280 sensor
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor #define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor
#define USE_SHT // Add I2C emulating code for SHT1X sensor
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0.3k mem) #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0.3k mem)

View File

@ -452,9 +452,18 @@ void handleAjax2()
#endif // USE_DHT #endif // USE_DHT
#ifdef USE_I2C #ifdef USE_I2C
if (i2c_flg) { if (i2c_flg) {
#ifdef USE_SHT
tpage += sht_webPresent();
#endif
#ifdef USE_HTU
tpage += htu_webPresent(); tpage += htu_webPresent();
#endif
#ifdef USE_BMP
tpage += bmp_webPresent(); tpage += bmp_webPresent();
#endif
#ifdef USE_BH1750
tpage += bh1750_webPresent(); tpage += bh1750_webPresent();
#endif
} }
#endif // USE_I2C #endif // USE_I2C
String page = ""; String page = "";

214
sonoff/xsns_sht1x.ino Normal file
View File

@ -0,0 +1,214 @@
/*
Copyright (c) 2017 Theo Arends. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef USE_I2C
#ifdef USE_SHT
/*********************************************************************************************\
* SHT1x - Temperature and Humidy
*
* Reading temperature and humidity takes about 320 milliseconds!
* Source: Marinus vd Broek https://github.com/ESP8266nu/ESPEasy
\*********************************************************************************************/
enum {
SHT1X_CMD_MEASURE_TEMP = B00000011,
SHT1X_CMD_MEASURE_RH = B00000101,
SHT1X_CMD_SOFT_RESET = B00011110
};
uint8_t sht_sda_pin, sht_scl_pin, shttype = 0;
boolean sht_reset()
{
pinMode(sht_sda_pin, INPUT_PULLUP);
pinMode(sht_scl_pin, OUTPUT);
delay(11);
for (byte i = 0; i < 9; i++) {
digitalWrite(sht_scl_pin, HIGH);
digitalWrite(sht_scl_pin, LOW);
}
boolean success = sht_sendCommand(SHT1X_CMD_SOFT_RESET);
delay(11);
return success;
}
boolean sht_sendCommand(const byte cmd)
{
pinMode(sht_sda_pin, OUTPUT);
// Transmission Start sequence
digitalWrite(sht_sda_pin, HIGH);
digitalWrite(sht_scl_pin, HIGH);
digitalWrite(sht_sda_pin, LOW);
digitalWrite(sht_scl_pin, LOW);
digitalWrite(sht_scl_pin, HIGH);
digitalWrite(sht_sda_pin, HIGH);
digitalWrite(sht_scl_pin, LOW);
// Send the command (address must be 000b)
shiftOut(sht_sda_pin, sht_scl_pin, MSBFIRST, cmd);
// Wait for ACK
boolean ackerror = false;
digitalWrite(sht_scl_pin, HIGH);
pinMode(sht_sda_pin, INPUT_PULLUP);
if (digitalRead(sht_sda_pin) != LOW) ackerror = true;
digitalWrite(sht_scl_pin, LOW);
delayMicroseconds(1); // Give the sensor time to release the data line
if (digitalRead(sht_sda_pin) != HIGH) ackerror = true;
if (ackerror) {
shttype = 0;
addLog_P(LOG_LEVEL_DEBUG, PSTR("SHT1X: Sensor did not ACK command"));
}
return (!ackerror);
}
boolean sht_awaitResult()
{
// Maximum 320ms for 14 bit measurement
for (byte i = 0; i < 16; i++) {
if (digitalRead(sht_sda_pin) == LOW) return true;
delay(20);
}
addLog_P(LOG_LEVEL_DEBUG, PSTR("SHT1X: Data not ready"));
shttype = 0;
return false;
}
int sht_readData()
{
int val = 0;
// Read most significant byte
val = shiftIn(sht_sda_pin, sht_scl_pin, 8);
val <<= 8;
// Send ACK
pinMode(sht_sda_pin, OUTPUT);
digitalWrite(sht_sda_pin, LOW);
digitalWrite(sht_scl_pin, HIGH);
digitalWrite(sht_scl_pin, LOW);
pinMode(sht_sda_pin, INPUT_PULLUP);
// Read least significant byte
val |= shiftIn(sht_sda_pin, sht_scl_pin, 8);
// Keep DATA pin high to skip CRC
digitalWrite(sht_scl_pin, HIGH);
digitalWrite(sht_scl_pin, LOW);
return val;
}
boolean sht_readTempHum(float &t, float &h)
{
float tempRaw, humRaw, rhLinear;
t = NAN;
h = NAN;
if (!sht_reset()) return false;
if (!sht_sendCommand(SHT1X_CMD_MEASURE_TEMP)) return false;
if (!sht_awaitResult()) return false;
tempRaw = sht_readData();
// Temperature conversion coefficients from SHT1X datasheet for version 4
const float d1 = -39.7; // 3.5V
const float d2 = 0.01; // 14-bit
t = d1 + (tempRaw * d2);
if (!sht_sendCommand(SHT1X_CMD_MEASURE_RH)) return false;
if (!sht_awaitResult()) return false;
humRaw = sht_readData();
// Temperature conversion coefficients from SHT1X datasheet for version 4
const float c1 = -2.0468;
const float c2 = 0.0367;
const float c3 = -1.5955E-6;
const float t1 = 0.01;
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;
return (!isnan(t) && !isnan(h));
}
boolean sht_readCharTempHum(char* temp, char* hum)
{
float t, h;
boolean success = sht_readTempHum(t, h);
dtostrf(t, 1, TEMP_RESOLUTION &3, temp);
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, hum);
return success;
}
boolean sht_detect()
{
if (shttype) return true;
float t, h;
sht_sda_pin = pin[GPIO_I2C_SDA];
sht_scl_pin = pin[GPIO_I2C_SCL];
if (sht_readTempHum(t, h)) {
shttype = 1;
addLog_P(LOG_LEVEL_DEBUG, PSTR("I2C: SHT1X found"));
} else {
Wire.begin(sht_sda_pin, sht_scl_pin);
shttype = 0;
}
return shttype;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void sht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
{
if (!shttype) return;
char stemp[10], shum[10];
if (sht_readCharTempHum(stemp, shum)) {
snprintf_P(svalue, ssvalue, PSTR("%s, \"SHT1X\":{\"Temperature\":%s, \"Humidity\":%s}"),
svalue, stemp, shum);
*djson = 1;
#ifdef USE_DOMOTICZ
domoticz_sensor2(stemp, shum);
#endif // USE_DOMOTICZ
}
}
#ifdef USE_WEBSERVER
String sht_webPresent()
{
String page = "";
if (shttype) {
char stemp[10], shum[10];
if (sht_readCharTempHum(stemp, shum)) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, (TEMP_CONVERSION) ? 'F' : 'C');
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, "SHT1X", shum);
page += sensor;
}
}
return page;
}
#endif // USE_WEBSERVER
#endif // USE_SHT
#endif // USE_I2C