mirror of https://github.com/arendst/Tasmota.git
v3.9.14
3.9.14 20170211 * Add False and True as alternatives for 0/Off and 1/On (#49) * Fix Status10 JSON format (#52) * Fix DS18x20 using OneWire library (#53)
This commit is contained in:
parent
3a07c9bf6a
commit
bb5251c2c8
|
@ -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.13** - See ```sonoff/_releasenotes.ino``` for change information.
|
||||
Current version is **3.9.14** - 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,9 @@
|
|||
/* 3.9.13 20170210
|
||||
/* 3.9.14 20170211
|
||||
* Add False and True as alternatives for 0/Off and 1/On (#49)
|
||||
* Fix Status10 JSON format (#52)
|
||||
* Fix DS18x20 using OneWire library (#53)
|
||||
*
|
||||
* 3.9.13 20170210
|
||||
* Add FlashChipSize to Status 4
|
||||
* Removed redundant DHT2 option and code
|
||||
* Add Sonoff SV GPIO pin 05 configuration (#40)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* ====================================================
|
||||
*/
|
||||
|
||||
#define VERSION 0x03090D00 // 3.9.13
|
||||
#define VERSION 0x03090E00 // 3.9.14
|
||||
|
||||
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};
|
||||
|
@ -46,10 +46,6 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#define MQTT_FINGERPRINT "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07"
|
||||
#endif
|
||||
|
||||
#ifndef USE_DHT2
|
||||
#define USE_DHT // Default DHT11 sensor needs no external library
|
||||
#endif
|
||||
|
||||
#ifndef USE_DS18x20
|
||||
#define USE_DS18B20 // Default DS18B20 sensor needs no external library
|
||||
#endif
|
||||
|
@ -59,6 +55,7 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#endif
|
||||
|
||||
#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address>
|
||||
#define USE_DHT // Default DHT11 sensor needs no external library
|
||||
#define CONFIG_FILE_SIGN 0xA5 // Configuration file signature
|
||||
#define CONFIG_FILE_XOR 0x5A // Configuration file xor (0 = No Xor)
|
||||
|
||||
|
@ -1147,8 +1144,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
if (!strcmp(dataBufUc,"?")) data_len = 0;
|
||||
int16_t payload = atoi(dataBuf); // -32766 - 32767
|
||||
uint16_t payload16 = atoi(dataBuf); // 0 - 65535
|
||||
if (!strcmp(dataBufUc,"OFF") || !strcmp(dataBufUc,"STOP")) payload = 0;
|
||||
if (!strcmp(dataBufUc,"ON") || !strcmp(dataBufUc,"START") || !strcmp(dataBufUc,"USER")) payload = 1;
|
||||
if (!strcmp(dataBufUc,"OFF") || !strcmp(dataBufUc,"FALSE") || !strcmp(dataBufUc,"STOP")) payload = 0;
|
||||
if (!strcmp(dataBufUc,"ON") || !strcmp(dataBufUc,"TRUE") || !strcmp(dataBufUc,"START") || !strcmp(dataBufUc,"USER")) payload = 1;
|
||||
if (!strcmp(dataBufUc,"TOGGLE") || !strcmp(dataBufUc,"ADMIN")) payload = 2;
|
||||
if (!strcmp(dataBufUc,"BLINK")) payload = 3;
|
||||
if (!strcmp(dataBufUc,"BLINKOFF")) payload = 4;
|
||||
|
@ -1272,7 +1269,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
else if (!strcmp(type,"GPIO") && (index < MAX_GPIO_PIN)) {
|
||||
mytmplt cmodule;
|
||||
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
|
||||
if ((data_len > 0) && (cmodule.gp.io[index] == GPIO_USER) && (payload >= GPIO_SENSOR_START) && (payload < GPIO_SENSOR_END)) {
|
||||
if ((data_len > 0) && (cmodule.gp.io[index] == GPIO_USER) && (payload >= 0) && (payload < GPIO_SENSOR_END)) {
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if ((cmodule.gp.io[i] == GPIO_USER) && (sysCfg.my_module.gp.io[i] == payload)) sysCfg.my_module.gp.io[i] = 0;
|
||||
}
|
||||
|
@ -1928,7 +1925,7 @@ void publish_status(uint8_t payload)
|
|||
uint8_t djson = 0;
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusSNS\":"));
|
||||
sensors_mqttPresent(svalue, sizeof(svalue), &djson);
|
||||
if (!djson) snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
|
||||
mqtt_publish_topic_P(option, PSTR("STATUS10"), svalue);
|
||||
}
|
||||
}
|
||||
|
@ -1948,9 +1945,9 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
|||
ds18x20_mqttPresent(svalue, ssvalue, djson);
|
||||
#endif // USE_DS18x20
|
||||
}
|
||||
#if defined(USE_DHT) || defined(USE_DHT2)
|
||||
#ifdef USE_DHT
|
||||
if (dht_type) dht_mqttPresent(svalue, ssvalue, djson);
|
||||
#endif // USE_DHT/2
|
||||
#endif // USE_DHT
|
||||
#ifdef USE_I2C
|
||||
if (i2c_flg) {
|
||||
#ifdef USE_HTU
|
||||
|
@ -2019,7 +2016,7 @@ void every_second()
|
|||
if (sysCfg.tele_period) {
|
||||
tele_period++;
|
||||
if (tele_period == sysCfg.tele_period -1) {
|
||||
if (pin[GPIO_DSB]) {
|
||||
if (pin[GPIO_DSB] < 99) {
|
||||
#ifdef USE_DS18B20
|
||||
dsb_readTempPrep();
|
||||
#endif // USE_DS18B20
|
||||
|
@ -2388,6 +2385,7 @@ void GPIO_init()
|
|||
if (sysCfg.my_module.gp.io[i] > GPIO_NONE) my_module.gp.io[i] = sysCfg.my_module.gp.io[i];
|
||||
if ((def_module.gp.io[i] > GPIO_NONE) && (def_module.gp.io[i] < GPIO_USER)) my_module.gp.io[i] = def_module.gp.io[i];
|
||||
}
|
||||
|
||||
for (byte i = 0; i < GPIO_MAX; i++) pin[i] = 99;
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
mpin = my_module.gp.io[i];
|
||||
|
@ -2404,13 +2402,13 @@ void GPIO_init()
|
|||
led_inverted[mpin - GPIO_LED1_INV] = 1;
|
||||
mpin -= 4;
|
||||
}
|
||||
else if (mpin == GPIO_DHT11) dht_type = DHT11;
|
||||
else if (mpin == GPIO_DHT11) dht_type = mpin;
|
||||
else if (mpin == GPIO_DHT21) {
|
||||
dht_type = DHT21;
|
||||
dht_type = mpin;
|
||||
mpin--;
|
||||
}
|
||||
else if (mpin == GPIO_DHT22) {
|
||||
dht_type = DHT22;
|
||||
dht_type = mpin;
|
||||
mpin -= 2;
|
||||
}
|
||||
pin[mpin] = i;
|
||||
|
@ -2460,9 +2458,13 @@ void GPIO_init()
|
|||
hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99));
|
||||
if (hlw_flg) hlw_init();
|
||||
|
||||
#if defined(USE_DHT) || defined(USE_DHT2)
|
||||
#ifdef USE_DHT
|
||||
if (dht_type) dht_init();
|
||||
#endif // USE_DHT/2
|
||||
#endif // USE_DHT
|
||||
|
||||
#ifdef USE_DS18x20
|
||||
if (pin[GPIO_DSB] < 99) ds18x20_init();
|
||||
#endif // USE_DS18x20
|
||||
|
||||
#ifdef USE_I2C
|
||||
i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99));
|
||||
|
|
|
@ -2,73 +2,95 @@
|
|||
* Template parameters
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define GPIO_SENSOR_START 0
|
||||
#define GPIO_NONE 0 // Not used
|
||||
#define GPIO_DHT11 1 // DHT11
|
||||
#define GPIO_DHT21 2 // DHT21
|
||||
#define GPIO_AM2301 2 // AM2301
|
||||
#define GPIO_DHT22 3 // DHT22
|
||||
#define GPIO_AM2302 3 // AM2302
|
||||
#define GPIO_AM2321 3 // AM2321
|
||||
#define GPIO_DSB 4 // Single wire DS18B20 or DS18S20
|
||||
#define GPIO_I2C_SCL 5 // I2C SCL
|
||||
#define GPIO_I2C_SDA 6 // I2C SDA
|
||||
#define GPIO_WS2812 7 // WS2812 Led string
|
||||
#define GPIO_SWT1 8 // User connected external switches
|
||||
#define GPIO_SENSOR_END 9
|
||||
// User selectable GPIO functionality
|
||||
enum upins_t {
|
||||
GPIO_NONE, // Not used
|
||||
GPIO_DHT11, // DHT11
|
||||
GPIO_DHT21, // DHT21, AM2301
|
||||
GPIO_DHT22, // DHT22, AM2302, AM2321
|
||||
GPIO_DSB, // Single wire DS18B20 or DS18S20
|
||||
GPIO_I2C_SCL, // I2C SCL
|
||||
GPIO_I2C_SDA, // I2C SDA
|
||||
GPIO_WS2812, // WS2812 Led string
|
||||
GPIO_SWT1, // User connected external switches
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
#define GPIO_SWT2 9
|
||||
#define GPIO_SWT3 10
|
||||
#define GPIO_SWT4 11
|
||||
#define GPIO_KEY1 12 // Button usually connected to GPIO0
|
||||
#define GPIO_KEY2 13
|
||||
#define GPIO_KEY3 14
|
||||
#define GPIO_KEY4 15
|
||||
#define GPIO_REL1 16 // Relays
|
||||
#define GPIO_REL2 17
|
||||
#define GPIO_REL3 18
|
||||
#define GPIO_REL4 19
|
||||
#define GPIO_REL1_INV 20
|
||||
#define GPIO_REL2_INV 21
|
||||
#define GPIO_REL3_INV 22
|
||||
#define GPIO_REL4_INV 23
|
||||
#define GPIO_LED1 24 // Leds
|
||||
#define GPIO_LED2 25
|
||||
#define GPIO_LED3 26
|
||||
#define GPIO_LED4 27
|
||||
#define GPIO_LED1_INV 28
|
||||
#define GPIO_LED2_INV 29
|
||||
#define GPIO_LED3_INV 30
|
||||
#define GPIO_LED4_INV 31
|
||||
#define GPIO_PWM0 32 // Cold
|
||||
#define GPIO_PWM1 33 // Warm
|
||||
#define GPIO_PWM2 34 // Red (swapped with Blue from original)
|
||||
#define GPIO_PWM3 35 // Green
|
||||
#define GPIO_PWM4 36 // Blue (swapped with Red from original)
|
||||
#define GPIO_RXD 37 // Serial interface
|
||||
#define GPIO_TXD 38 // Serial interface
|
||||
#define GPIO_HLW_SEL 39 // HLW8012 Sel output (Sonoff Pow)
|
||||
#define GPIO_HLW_CF1 40 // HLW8012 CF1 voltage / current (Sonoff Pow)
|
||||
#define GPIO_HLW_CF 41 // HLW8012 CF power (Sonoff Pow)
|
||||
#define GPIO_USER 42 // User configurable
|
||||
#define GPIO_MAX 43
|
||||
// Text in webpage Module Parameters and commands GPIOS and GPIO
|
||||
const char sensors[GPIO_SENSOR_END][8] PROGMEM = {
|
||||
"None",
|
||||
"DHT11",
|
||||
"AM2301",
|
||||
"DHT22",
|
||||
"DS18x20",
|
||||
"I2C SCL",
|
||||
"I2C SDA",
|
||||
"WS2812",
|
||||
"Switch" };
|
||||
|
||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||
enum fpins_t {
|
||||
GPIO_SWT2 = GPIO_SENSOR_END,
|
||||
GPIO_SWT3,
|
||||
GPIO_SWT4,
|
||||
GPIO_KEY1, // Button usually connected to GPIO0
|
||||
GPIO_KEY2,
|
||||
GPIO_KEY3,
|
||||
GPIO_KEY4,
|
||||
GPIO_REL1, // Relays
|
||||
GPIO_REL2,
|
||||
GPIO_REL3,
|
||||
GPIO_REL4,
|
||||
GPIO_REL1_INV,
|
||||
GPIO_REL2_INV,
|
||||
GPIO_REL3_INV,
|
||||
GPIO_REL4_INV,
|
||||
GPIO_LED1, // Leds
|
||||
GPIO_LED2,
|
||||
GPIO_LED3,
|
||||
GPIO_LED4,
|
||||
GPIO_LED1_INV,
|
||||
GPIO_LED2_INV,
|
||||
GPIO_LED3_INV,
|
||||
GPIO_LED4_INV,
|
||||
GPIO_PWM0, // Cold
|
||||
GPIO_PWM1, // Warm
|
||||
GPIO_PWM2, // Red (swapped with Blue from original)
|
||||
GPIO_PWM3, // Green
|
||||
GPIO_PWM4, // Blue (swapped with Red from original)
|
||||
GPIO_RXD, // Serial interface
|
||||
GPIO_TXD, // Serial interface
|
||||
GPIO_HLW_SEL, // HLW8012 Sel output (Sonoff Pow)
|
||||
GPIO_HLW_CF1, // HLW8012 CF1 voltage / current (Sonoff Pow)
|
||||
GPIO_HLW_CF, // HLW8012 CF power (Sonoff Pow)
|
||||
GPIO_USER, // User configurable
|
||||
GPIO_MAX };
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
enum module_t {SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, S20, SLAMPHER, SONOFF_TOUCH, SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, USER_TEST, MAXMODULE};
|
||||
// Supported hardware modules
|
||||
enum module_t {
|
||||
SONOFF_BASIC,
|
||||
SONOFF_RF,
|
||||
SONOFF_SV,
|
||||
SONOFF_TH,
|
||||
SONOFF_DUAL,
|
||||
SONOFF_POW,
|
||||
SONOFF_4CH,
|
||||
S20,
|
||||
SLAMPHER,
|
||||
SONOFF_TOUCH,
|
||||
SONOFF_LED,
|
||||
CH1,
|
||||
CH4,
|
||||
MOTOR,
|
||||
ELECTRODRAGON,
|
||||
USER_TEST,
|
||||
MAXMODULE };
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
#define MAX_GPIO_PIN 17 // Number of supported GPIO
|
||||
|
||||
#define DHT11 11
|
||||
#define DHT21 21
|
||||
#define AM2301 21
|
||||
#define DHT22 22
|
||||
#define AM2302 22
|
||||
#define AM2321 22
|
||||
|
||||
typedef struct MYIO {
|
||||
uint8_t io[MAX_GPIO_PIN];
|
||||
} myio;
|
||||
|
@ -78,9 +100,7 @@ typedef struct MYTMPLT {
|
|||
myio gp;
|
||||
} mytmplt;
|
||||
|
||||
const char sensors[GPIO_SENSOR_END][8] PROGMEM =
|
||||
{ "None", "DHT11", "AM2301", "DHT22", "DS18x20", "I2C SCL", "I2C SDA", "WS2812", "Switch" };
|
||||
|
||||
// Default module settings
|
||||
const mytmplt modules[MAXMODULE] PROGMEM = {
|
||||
{ "Sonoff Basic", // Sonoff Basic
|
||||
GPIO_KEY1, // GPIO00 Button
|
||||
|
|
|
@ -491,11 +491,11 @@ void handleRoot()
|
|||
if (pin[GPIO_DSB] < 99) tpage += dsb_webPresent();
|
||||
#endif // USE_DS18B20
|
||||
#ifdef USE_DS18x20
|
||||
if (pin[GPIO_DSB] < 99) page += ds18x20_webPresent();
|
||||
if (pin[GPIO_DSB] < 99) tpage += ds18x20_webPresent();
|
||||
#endif // USE_DS18x20
|
||||
#if defined(USE_DHT) || defined(USE_DHT2)
|
||||
#ifdef USE_DHT
|
||||
if (dht_type) tpage += dht_webPresent();
|
||||
#endif // USE_DHT/2
|
||||
#endif // USE_DHT
|
||||
#ifdef USE_I2C
|
||||
if (i2c_flg) {
|
||||
tpage += htu_webPresent();
|
||||
|
@ -570,7 +570,7 @@ void handleModule()
|
|||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (cmodule.gp.io[i] == GPIO_USER) {
|
||||
page += F("<br/><b>GPIO"); page += String(i); page += F("</b> <select id='g"); page += String(i); page += F("' name='g"); page += String(i); page += F("'>");
|
||||
for (byte j = GPIO_SENSOR_START; j < GPIO_SENSOR_END; j++) {
|
||||
for (byte j = 0; j < GPIO_SENSOR_END; j++) {
|
||||
page += F("<option ");
|
||||
if (j == my_module.gp.io[i]) page += F("selected ");
|
||||
page += F("value='"); page += String(j); page += F("'>");
|
||||
|
|
|
@ -137,13 +137,13 @@ boolean dht_readTempHum(bool S, float &t, float &h)
|
|||
|
||||
if (dht_read()) {
|
||||
switch (dht_type) {
|
||||
case DHT11:
|
||||
case GPIO_DHT11:
|
||||
h = data[0];
|
||||
t = data[2];
|
||||
if(S) t = dht_convertCtoF(t);
|
||||
break;
|
||||
case DHT22:
|
||||
case DHT21:
|
||||
case GPIO_DHT22:
|
||||
case GPIO_DHT21:
|
||||
h = data[0];
|
||||
h *= 256;
|
||||
h += data[1];
|
||||
|
|
|
@ -36,23 +36,28 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <OneWire.h>
|
||||
|
||||
OneWire ds(pin[GPIO_DSB]);
|
||||
OneWire *ds = NULL;
|
||||
|
||||
uint8_t ds18x20_addr[DS18X20_MAX_SENSORS][8];
|
||||
uint8_t ds18x20_idx[DS18X20_MAX_SENSORS];
|
||||
uint8_t ds18x20_snsrs = 0;
|
||||
|
||||
void ds18x20_init()
|
||||
{
|
||||
ds = new OneWire(pin[GPIO_DSB]);
|
||||
}
|
||||
|
||||
void ds18x20_search()
|
||||
{
|
||||
uint8_t num_sensors=0;
|
||||
uint8_t sensor = 0;
|
||||
uint8_t i;
|
||||
|
||||
ds.reset_search();
|
||||
ds->reset_search();
|
||||
for (num_sensors = 0; num_sensors < DS18X20_MAX_SENSORS; num_sensors)
|
||||
{
|
||||
if (!ds.search(ds18x20_addr[num_sensors])) {
|
||||
ds.reset_search();
|
||||
if (!ds->search(ds18x20_addr[num_sensors])) {
|
||||
ds->reset_search();
|
||||
break;
|
||||
}
|
||||
// If CRC Ok and Type DS18S20 or DS18B20
|
||||
|
@ -104,9 +109,9 @@ String ds18x20_type(uint8_t sensor)
|
|||
|
||||
void ds18x20_convert()
|
||||
{
|
||||
ds.reset();
|
||||
ds.write(W1_SKIP_ROM); // Address all Sensors on Bus
|
||||
ds.write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
|
||||
ds->reset();
|
||||
ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
|
||||
ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
|
||||
// delay(750); // 750ms should be enough for 12bit conv
|
||||
}
|
||||
|
||||
|
@ -125,11 +130,11 @@ boolean ds18x20_read(uint8_t sensor, bool S, float &t)
|
|||
|
||||
t = NAN;
|
||||
|
||||
ds.reset();
|
||||
ds.select(ds18x20_addr[ds18x20_idx[sensor]]);
|
||||
ds.write(W1_READ_SCRATCHPAD); // Read Scratchpad
|
||||
ds->reset();
|
||||
ds->select(ds18x20_addr[ds18x20_idx[sensor]]);
|
||||
ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad
|
||||
|
||||
for (i = 0; i < 9; i++) data[i] = ds.read();
|
||||
for (i = 0; i < 9; i++) data[i] = ds->read();
|
||||
if (OneWire::crc8(data, 8) == data[8]) {
|
||||
switch(ds18x20_addr[ds18x20_idx[sensor]][0]) {
|
||||
case 0x10: // DS18S20
|
||||
|
|
Loading…
Reference in New Issue