4.1.0 20170325
* Change static IP addresses in user_config.h from list (using commas)
to string (using dots)
* Unify display result of commands Modules, Module and Gpios
* Rewrite Module selection web page to bring size down from 18651 to
4319 bytes (!) (#234, #240)
* Add basic support for (Lixada) H801 RGBWW controller (#252)
* Add command Prefix1 to Prefix3 to assign SUB_PREFIX, PUB_PREFIX and
PUB_PREFIX2 respectively (#255)
* Add static ip addresses to flash (#262)
* Add commands IpAddress, Gateway, Subnetmask and DnsServer to select
static ip addresses (#273)
This commit is contained in:
arendst 2017-03-25 17:24:11 +01:00
parent 99b7474ac4
commit ae27ec26a4
13 changed files with 209 additions and 83 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 **4.0.8** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
Current version is **4.1.0** - 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.
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,13 @@
/* 4.0.8 20170321
/* 4.1.0 20170325
* Change static IP addresses in user_config.h from list (using commas) to string (using dots)
* Unify display result of commands Modules, Module and Gpios
* Rewrite Module selection web page to bring size down from 18651 to 4319 bytes (!) (#234, #240)
* Add basic support for (Lixada) H801 RGBWW controller (#252)
* Add command Prefix1 to Prefix3 to assign SUB_PREFIX, PUB_PREFIX and PUB_PREFIX2 respectively (#255)
* Add static ip addresses to flash (#262)
* Add commands IpAddress, Gateway, Subnetmask and DnsServer to select static ip addresses (#273)
*
* 4.0.8 20170321
* Fix entering non-numeric webpassword
* Force selection between TLS or Webserver due to memory restraint (#240)
* Allow entering empty string using "0" for selected commands (#242)

View File

@ -83,7 +83,8 @@ struct SYSCFG {
byte model; // Not used since 3.9.1
int8_t timezone;
char otaUrl[101];
char ex_friendlyname[33]; // Not used since 3.2.5 - see below
char mqtt_prefix[3][11]; // was ex_friendlyname[33] until 3.2.5
byte serial_enable;
byte seriallog_level;
@ -210,6 +211,10 @@ struct SYSCFG {
// 4.0.7
uint16_t pwmvalue[5];
// 4.0.9
// uint8_t ip_address[4][4];
uint32_t ip_address[4];
} sysCfg;
struct RTCMEM {

View File

@ -418,10 +418,9 @@ void CFG_DefaultSet2()
{
sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE;
sysCfg.model = 0;
// sysCfg.model = 0;
sysCfg.timezone = APP_TIMEZONE;
strlcpy(sysCfg.otaUrl, OTA_URL, sizeof(sysCfg.otaUrl));
strlcpy(sysCfg.ex_friendlyname, FRIENDLY_NAME, sizeof(sysCfg.ex_friendlyname));
sysCfg.seriallog_level = SERIAL_LOG_LEVEL;
sysCfg.sta_active = 0;
@ -451,14 +450,11 @@ void CFG_DefaultSet2()
sysCfg.mqtt_power_retain = MQTT_POWER_RETAIN;
sysCfg.value_units = 0;
sysCfg.button_restrict = 0;
// sysCfg.message_format = 0;
sysCfg.tele_period = TELE_PERIOD;
sysCfg.power = APP_POWER;
sysCfg.poweronstate = APP_POWERON_STATE;
// sysCfg.pulsetime = APP_PULSETIME;
sysCfg.ledstate = APP_LEDSTATE;
// sysCfg.switchmode = SWITCH_MODE;
sysCfg.blinktime = APP_BLINKTIME;
sysCfg.blinkcount = APP_BLINKCOUNT;
sysCfg.sleep = APP_SLEEP;
@ -495,7 +491,7 @@ void CFG_DefaultSet2()
sysCfg.hlw_mkwhs = 0; // MaxEnergyStart
CFG_DefaultSet_3_2_4();
strlcpy(sysCfg.friendlyname[0], FRIENDLY_NAME, sizeof(sysCfg.friendlyname[0]));
strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1]));
strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2]));
@ -514,8 +510,11 @@ void CFG_DefaultSet2()
CFG_DefaultSet_4_0_4();
sysCfg.pulsetime[0] = APP_PULSETIME;
// v4.0.7
// 4.0.7
for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0;
// 4.0.9
CFG_DefaultSet_4_0_9();
}
void CFG_DefaultSet_3_2_4()
@ -564,6 +563,17 @@ void CFG_DefaultSet_4_0_4()
for (byte i = 1; i < MAX_PULSETIMERS; i++) sysCfg.pulsetime[i] = 0;
}
void CFG_DefaultSet_4_0_9()
{
strlcpy(sysCfg.mqtt_prefix[0], SUB_PREFIX, sizeof(sysCfg.mqtt_prefix[0]));
strlcpy(sysCfg.mqtt_prefix[1], PUB_PREFIX, sizeof(sysCfg.mqtt_prefix[1]));
strlcpy(sysCfg.mqtt_prefix[2], PUB_PREFIX2, sizeof(sysCfg.mqtt_prefix[2]));
parseIP(&sysCfg.ip_address[0], WIFI_IP_ADDRESS);
parseIP(&sysCfg.ip_address[1], WIFI_GATEWAY);
parseIP(&sysCfg.ip_address[2], WIFI_SUBNETMASK);
parseIP(&sysCfg.ip_address[3], WIFI_DNS);
}
void CFG_Default()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration"));
@ -600,7 +610,7 @@ void CFG_Migrate_Part2()
strlcpy(sysCfg.mqtt_client, sysCfg2.mqtt_client, sizeof(sysCfg.mqtt_client));
strlcpy(sysCfg.mqtt_user, sysCfg2.mqtt_user, sizeof(sysCfg.mqtt_user));
strlcpy(sysCfg.mqtt_pwd, sysCfg2.mqtt_pwd, sizeof(sysCfg.mqtt_pwd));
strlcpy(sysCfg.ex_friendlyname, sysCfg2.mqtt_client, sizeof(sysCfg.ex_friendlyname));
strlcpy(sysCfg.friendlyname[0], sysCfg2.mqtt_client, sizeof(sysCfg.friendlyname[0]));
}
if (sysCfg2.version >= 0x01001700) { // 1.0.23
sysCfg.webserver = sysCfg2.webserver;
@ -691,19 +701,13 @@ void CFG_Delta()
if (sysCfg.version < 0x03000600) { // 3.0.6 - Add parameter
sysCfg.ex_pulsetime = APP_PULSETIME;
}
if (sysCfg.version < 0x03010100) { // 3.1.1 - Add parameter
sysCfg.poweronstate = APP_POWERON_STATE;
}
if (sysCfg.version < 0x03010200) { // 3.1.2 - Add parameter
if (sysCfg.poweronstate == 2) sysCfg.poweronstate = 3;
sysCfg.poweronstate = APP_POWERON_STATE;
}
if (sysCfg.version < 0x03010600) { // 3.1.6 - Add parameter
sysCfg.blinktime = APP_BLINKTIME;
sysCfg.blinkcount = APP_BLINKCOUNT;
}
if (sysCfg.version < 0x03011000) { // 3.1.16 - Add parameter
getClient(sysCfg.friendlyname[0], sysCfg.mqtt_client, sizeof(sysCfg.friendlyname[0]));
}
if (sysCfg.version < 0x03020400) { // 3.2.4 - Add parameter
CFG_DefaultSet_3_2_4();
}
@ -746,6 +750,9 @@ void CFG_Delta()
if (sysCfg.version < 0x04000700) {
for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0;
}
if (sysCfg.version < 0x04000804) {
CFG_DefaultSet_4_0_9();
}
sysCfg.version = VERSION;
}
}

View File

@ -12,9 +12,9 @@
//#define ALLOW_MIGRATE_TO_V3
#ifdef ALLOW_MIGRATE_TO_V3
#define VERSION 0x03091F00 // 3.9.31
#define VERSION 0x03092000 // 3.9.32
#else
#define VERSION 0x04000800 // 4.0.8
#define VERSION 0x04010000 // 4.1.0
#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};
@ -132,7 +132,11 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
#define INPUT_BUFFER_SIZE 100 // Max number of characters in serial buffer
#define TOPSZ 60 // Max number of characters in topic string
#define LOGSZ 128 // Max number of characters in log string
#define MAX_LOG_LINES 20 // Max number of lines in weblog
#ifdef USE_MQTT_TLS
#define MAX_LOG_LINES 10 // Max number of lines in weblog
#else
#define MAX_LOG_LINES 20 // Max number of lines in weblog
#endif
#define APP_BAUDRATE 115200 // Default serial baudrate
#define MAX_STATUS 11 // Max number of status lines
@ -208,13 +212,6 @@ struct TimeChangeRule
TimeChangeRule myDST = { TIME_DST }; // Daylight Saving Time
TimeChangeRule mySTD = { TIME_STD }; // Standard Time
#ifdef USE_STATIC_IP_ADDRESS
const uint8_t ipadd[4] = { WIFI_IP_ADDRESS }; // Static ip
const uint8_t ipgat[4] = { WIFI_GATEWAY }; // Local router gateway ip
const uint8_t ipdns[4] = { WIFI_DNS }; // DNS ip
const uint8_t ipsub[4] = { WIFI_SUBNETMASK }; // Subnetmask
#endif // USE_STATIC_IP_ADDRESS
int Baudrate = APP_BAUDRATE; // Serial interface baud rate
byte SerialInByte; // Received byte
int SerialInByteCounter = 0; // Index in receive buffer
@ -435,8 +432,8 @@ void mqtt_publish(const char* topic, const char* data, boolean retained)
{
char *me;
if (!strcmp(SUB_PREFIX,PUB_PREFIX)) {
me = strstr(topic,SUB_PREFIX);
if (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1])) {
me = strstr(topic,sysCfg.mqtt_prefix[0]);
if (me == topic) mqtt_cmnd_publish += 8;
}
mqtt_publish_sec(topic, data, retained);
@ -452,7 +449,7 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data
char romram[16], stopic[TOPSZ];
snprintf_P(romram, sizeof(romram), subtopic);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), (prefix) ? PUB_PREFIX2 : PUB_PREFIX, sysCfg.mqtt_topic, romram);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), sysCfg.mqtt_prefix[prefix +1], sysCfg.mqtt_topic, romram);
mqtt_publish(stopic, data);
}
@ -462,7 +459,7 @@ void mqtt_publishPowerState(byte device)
if ((device < 1) || (device > Maxdevice)) device = 1;
snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/RESULT"), PUB_PREFIX, sysCfg.mqtt_topic);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/RESULT"), sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"%s%s\":\"%s\"}"),
sysCfg.mqtt_subtopic, (Maxdevice > 1) ? sdevice : "", (power & (0x01 << (device -1))) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
mqtt_publish(stopic, svalue);
@ -488,17 +485,17 @@ void mqtt_connected()
if (sysCfg.mqtt_enabled) {
// Satisfy iobroker (#299)
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/POWER"), SUB_PREFIX, sysCfg.mqtt_topic);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/POWER"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic);
svalue[0] ='\0';
mqtt_publish(stopic, svalue);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), SUB_PREFIX, sysCfg.mqtt_topic);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic);
mqttClient.subscribe(stopic);
mqttClient.loop(); // Solve LmacRxBlk:1 messages
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), SUB_PREFIX, sysCfg.mqtt_grptopic);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_grptopic);
mqttClient.subscribe(stopic);
mqttClient.loop(); // Solve LmacRxBlk:1 messages
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), SUB_PREFIX, MQTTClient); // Fall back topic
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/#"), sysCfg.mqtt_prefix[0], MQTTClient); // Fall back topic
mqttClient.subscribe(stopic);
mqttClient.loop(); // Solve LmacRxBlk:1 messages
#ifdef USE_DOMOTICZ
@ -576,7 +573,7 @@ void mqtt_reconnect()
#endif // USE_DISCOVERY
#endif // USE_MQTT_TLS
mqttClient.setServer(sysCfg.mqtt_host, sysCfg.mqtt_port);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/LWT"), PUB_PREFIX2, sysCfg.mqtt_topic);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/LWT"), sysCfg.mqtt_prefix[2], sysCfg.mqtt_topic);
snprintf_P(svalue, sizeof(svalue), PSTR("Offline"));
if (mqttClient.connect(MQTTClient, sysCfg.mqtt_user, sysCfg.mqtt_pwd, stopic, 1, true, svalue)) {
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Connected"));
@ -643,6 +640,17 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
}
snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
}
else if (!strcmp(type,"PREFIX") && (index > 0) && (index <= 3)) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_prefix[0]))) {
for(i = 0; i <= data_len; i++)
// if ((dataBuf[i] == '/') || (dataBuf[i] == '+') || (dataBuf[i] == '#') || (dataBuf[i] == ' ')) dataBuf[i] = '_';
if ((dataBuf[i] == '+') || (dataBuf[i] == '#') || (dataBuf[i] == ' ')) dataBuf[i] = '_';
strlcpy(sysCfg.mqtt_prefix[index -1], (payload == 1) ? (index==1)?SUB_PREFIX:(index==2)?PUB_PREFIX:PUB_PREFIX : dataBuf, sizeof(sysCfg.mqtt_prefix[0]));
// if (sysCfg.mqtt_prefix[index -1][strlen(sysCfg.mqtt_prefix[index -1])] == '/') sysCfg.mqtt_prefix[index -1][strlen(sysCfg.mqtt_prefix[index -1])] = 0;
restartflag = 2;
}
snprintf_P(svalue, ssvalue, PSTR("{\"Prefix%d\":\"%s\"}"), index, sysCfg.mqtt_prefix[index -1]);
}
else if (!strcmp(type,"GROUPTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_grptopic))) {
for(i = 0; i <= data_len; i++)
@ -710,9 +718,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
if (!payload) {
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"), PUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
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);
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/LIGHT%s"), PUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s/%s/LIGHT%s"), sysCfg.mqtt_prefix[1], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp2 : "");
mqtt_publish(stemp1, "", sysCfg.mqtt_power_retain);
}
}
@ -738,8 +746,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
{
char *str;
if (!strcmp(SUB_PREFIX,PUB_PREFIX)) {
str = strstr(topic,SUB_PREFIX);
if (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1])) {
str = strstr(topic,sysCfg.mqtt_prefix[0]);
if ((str == topic) && mqtt_cmnd_publish) {
if (mqtt_cmnd_publish > 8) mqtt_cmnd_publish -= 8; else mqtt_cmnd_publish = 0;
return;
@ -749,6 +757,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
char topicBuf[TOPSZ], dataBuf[data_len+1], dataBufUc[128], svalue[MESSZ], stemp1[TOPSZ];
char *p, *mtopic = NULL, *type = NULL;
uint16_t i = 0, grpflg = 0, index;
uint32_t address;
strncpy(topicBuf, topic, sizeof(topicBuf));
memcpy(dataBuf, data, sizeof(dataBuf));
@ -764,7 +773,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
#endif // USE_DOMOTICZ
memmove(topicBuf, topicBuf+sizeof(SUB_PREFIX), sizeof(topicBuf)-sizeof(SUB_PREFIX)); // Remove SUB_PREFIX
memmove(topicBuf, topicBuf+strlen(sysCfg.mqtt_prefix[0]), sizeof(topicBuf)-strlen(sysCfg.mqtt_prefix[0])); // Remove SUB_PREFIX
i = 0;
for (str = strtok_r(topicBuf, "/", &p); str && i < 2; str = strtok_r(NULL, "/", &p)) {
@ -891,7 +900,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
restartflag = 2;
}
snprintf_P(stemp1, sizeof(stemp1), modules[sysCfg.module].name);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Module\":\"%s (%d)\"}"), stemp1, sysCfg.module +1);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Module\":\"%d (%s)\"}"), sysCfg.module +1, stemp1);
}
else if (!strcmp(type,"MODULES")) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Modules1\":\""), svalue);
@ -900,7 +909,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
if (jsflg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue);
jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), modules[i].name);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s (%d)"), svalue, stemp1, i +1);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i +1, stemp1);
}
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
mqtt_publish_topic_P(0, PSTR("RESULT"), svalue);
@ -910,7 +919,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
if (jsflg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue);
jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), modules[i].name);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s (%d)"), svalue, stemp1, i +1);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i +1, stemp1);
}
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
}
@ -947,7 +956,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
if (jsflg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue);
jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), sensors[i]);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s (%d)"), svalue, stemp1, i);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i, stemp1);
}
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
mqtt_publish_topic_P(0, PSTR("RESULT"), svalue);
@ -957,7 +966,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
if (jsflg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, "), svalue);
jsflg = 1;
snprintf_P(stemp1, sizeof(stemp1), sensors[i]);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s (%d)"), svalue, stemp1, i);
snprintf_P(svalue, sizeof(svalue), PSTR("%s%d (%s)"), svalue, i, stemp1);
}
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
}
@ -1032,13 +1041,41 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"LogPort\":%d}"), sysCfg.syslog_port);
}
else if (!strcmp(type,"IPADDRESS")) {
if (parseIP(&address, dataBuf)) {
sysCfg.ip_address[0] = address;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"IPAddress\":\"%s (%s)\"}"), IPAddress(sysCfg.ip_address[0]).toString().c_str(), WiFi.localIP().toString().c_str());
}
else if (!strcmp(type,"GATEWAY")) {
if (parseIP(&address, dataBuf)) {
sysCfg.ip_address[1] = address;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Gateway\":\"%s\"}"), IPAddress(sysCfg.ip_address[1]).toString().c_str());
}
else if (!strcmp(type,"SUBNETMASK")) {
if (parseIP(&address, dataBuf)) {
sysCfg.ip_address[2] = address;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Subnetmask\":\"%s\"}"), IPAddress(sysCfg.ip_address[2]).toString().c_str());
}
else if (!strcmp(type,"DNSSERVER")) {
if (parseIP(&address, dataBuf)) {
sysCfg.ip_address[3] = address;
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"DnsServer\":\"%s\"}"), IPAddress(sysCfg.ip_address[3]).toString().c_str());
}
else if (!strcmp(type,"NTPSERVER") && (index > 0) && (index <= 3)) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.ntp_server[0]))) {
strlcpy(sysCfg.ntp_server[index -1], (!strcmp(dataBuf,"0")) ? "" : (payload == 1) ? (index==1)?NTP_SERVER1:(index==2)?NTP_SERVER2:NTP_SERVER3 : dataBuf, sizeof(sysCfg.ntp_server[0]));
for (i = 0; i < strlen(sysCfg.ntp_server[index -1]); i++) if (sysCfg.ntp_server[index -1][i] == ',') sysCfg.ntp_server[index -1][i] = '.';
restartflag = 2;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"NTPServer%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"NtpServer%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]);
}
else if (!strcmp(type,"AP")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
@ -1302,7 +1339,7 @@ void send_button_power(byte key, byte device, byte state)
if (!key && (device > Maxdevice)) device = 1;
snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s%s"),
SUB_PREFIX, (key) ? sysCfg.switch_topic : sysCfg.button_topic, sysCfg.mqtt_subtopic, (key || (Maxdevice > 1)) ? stemp1 : "");
sysCfg.mqtt_prefix[0], (key) ? sysCfg.switch_topic : sysCfg.button_topic, sysCfg.mqtt_subtopic, (key || (Maxdevice > 1)) ? stemp1 : "");
if (state == 3) {
svalue[0] = '\0';
@ -1401,7 +1438,7 @@ void do_cmnd(char *cmnd)
start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble
if (start) token = start;
}
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), SUB_PREFIX, sysCfg.mqtt_topic, token);
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/%s"), sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic, token);
token = strtok(NULL, "");
snprintf_P(svalue, sizeof(svalue), PSTR("%s"), (token == NULL) ? "" : token);
mqttDataCb(stopic, (byte*)svalue, strlen(svalue));
@ -1413,7 +1450,7 @@ void publish_status(uint8_t payload)
uint8_t option = 0;
// Workaround MQTT - TCP/IP stack queueing when SUB_PREFIX = PUB_PREFIX
option = (!strcmp(SUB_PREFIX,PUB_PREFIX) && (!payload));
option = (!strcmp(sysCfg.mqtt_prefix[0],sysCfg.mqtt_prefix[1]) && (!payload));
if ((!sysCfg.mqtt_enabled) && (payload == 6)) payload = 99;
if ((!hlw_flg) && ((payload == 8) || (payload == 9))) payload = 99;
@ -1452,8 +1489,8 @@ void publish_status(uint8_t payload)
}
if ((payload == 0) || (payload == 5)) {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusNET\":{\"Host\":\"%s\", \"IP\":\"%s\", \"Gateway\":\"%s\", \"Subnetmask\":\"%s\", \"Mac\":\"%s\", \"Webserver\":%d, \"WifiConfig\":%d}}"),
Hostname, WiFi.localIP().toString().c_str(), WiFi.gatewayIP().toString().c_str(), WiFi.subnetMask().toString().c_str(),
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusNET\":{\"Host\":\"%s\", \"IP\":\"%s\", \"Gateway\":\"%s\", \"Subnetmask\":\"%s\", \"DNSServer\":\"%s\", \"Mac\":\"%s\", \"Webserver\":%d, \"WifiConfig\":%d}}"),
Hostname, WiFi.localIP().toString().c_str(), IPAddress(sysCfg.ip_address[1]).toString().c_str(), IPAddress(sysCfg.ip_address[2]).toString().c_str(), IPAddress(sysCfg.ip_address[3]).toString().c_str(),
WiFi.macAddress().c_str(), sysCfg.webserver, sysCfg.sta_config);
mqtt_publish_topic_P(option, PSTR("STATUS5"), svalue);
}
@ -2020,6 +2057,8 @@ void GPIO_init()
}
}
if (pin[GPIO_TXD] == 2) Serial.set_tx(2);
analogWriteRange(PWM_RANGE); // Default is 1023 (Arduino.h)
analogWriteFreq(PWM_FREQ); // Default is 1000 (core_esp8266_wiring_pwm.c)

View File

@ -120,6 +120,7 @@ enum module_t {
WION,
WEMOS,
SONOFF_DEV,
H801,
MAXMODULE };
/********************************************************************************************/
@ -376,6 +377,20 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
0, // GPIO15
0, // GPIO16
GPIO_ADC0 // ADC0 A0 Analog input
},
{ "H801", // Lixada H801 Wifi (ESP8266)
GPIO_KEY1, // GPIO00 E-FW Button
GPIO_LED1, // GPIO01 Green LED
GPIO_TXD, // GPIO02 RX - Pin next to TX on the PCB
GPIO_RXD, // GPIO03 TX - Pin next to GND on the PCB
GPIO_PWM2, // GPIO04 W2
GPIO_LED2_INV, // GPIO05 Red LED
0, 0, 0, 0, 0, 0, // Flash connection
GPIO_PWM3, // GPIO12 Blue
GPIO_PWM4, // GPIO13 Green
GPIO_PWM1, // GPIO14 W1
GPIO_PWM5, // GPIO15 Red
0, 0
}
};

View File

@ -144,6 +144,42 @@ Decoding 14 results
}
#endif // DEBUG_THEO
/*********************************************************************************************\
* General
\*********************************************************************************************/
boolean parseIPx(char* str, uint16_t len, uint32_t* addr)
{
uint8_t *part = (uint8_t *)addr;
byte i;
if (!len) return false;
*addr = 0;
for (i = 0; i <= len; i++) if (*(str +i) == ',') *(str +i) = '.';
for (i = 0; i < 4; i++) {
part[i] = strtoul(str, NULL, 10); // Convert byte
str = strchr(str, '.');
if (str == NULL || *str == '\0') break; // No more separators, exit
str++; // Point to next character after separator
}
return (i == 3);
}
boolean parseIP(uint32_t* addr, const char* str)
{
uint8_t *part = (uint8_t*)addr;
byte i;
*addr = 0;
for (i = 0; i < 4; i++) {
part[i] = strtoul(str, NULL, 10); // Convert byte
str = strchr(str, '.');
if (str == NULL || *str == '\0') break; // No more separators, exit
str++; // Point to next character after separator
}
return (i == 3);
}
/*********************************************************************************************\
* Wifi
\*********************************************************************************************/
@ -285,9 +321,8 @@ void WIFI_begin(uint8_t flag)
sysCfg.sta_active ^= 1;
} // 3: Current AP
if (strlen(sysCfg.sta_ssid[1]) == 0) sysCfg.sta_active = 0;
#ifdef USE_STATIC_IP_ADDRESS
WiFi.config(ipadd, ipgat, ipsub, ipdns); // Set static IP
#endif // USE_STATIC_IP_ADDRESS
if (sysCfg.ip_address[0])
WiFi.config(sysCfg.ip_address[0], sysCfg.ip_address[1], sysCfg.ip_address[2], sysCfg.ip_address[3]); // Set static IP
WiFi.hostname(Hostname);
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..."),
@ -301,6 +336,12 @@ void WIFI_check_ip()
_wificounter = WIFI_CHECK_SEC;
_wifiretry = WIFI_RETRY_SEC;
addLog_P((_wifistatus != WL_CONNECTED) ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG_MORE, PSTR("Wifi: Connected"));
if (_wifistatus != WL_CONNECTED) {
// addLog_P(LOG_LEVEL_INFO, PSTR("Wifi: Set IP addresses"));
sysCfg.ip_address[1] = (uint32_t)WiFi.gatewayIP();
sysCfg.ip_address[2] = (uint32_t)WiFi.subnetMask();
sysCfg.ip_address[3] = (uint32_t)WiFi.dnsIP();
}
_wifistatus = WL_CONNECTED;
} else {
_wifistatus = WiFi.status();

View File

@ -17,11 +17,11 @@
#define SAVE_STATE 1 // [SaveState] Save changed power state to Flash (0 = disable, 1 = enable)
// -- Wifi ----------------------------------------
//#define USE_STATIC_IP_ADDRESS // Enable optional static IP address (Use DHCP by disabling using //)
#define WIFI_IP_ADDRESS 192,168,2,72 // IP address using commas
#define WIFI_GATEWAY 192,168,2,254 // Gateway IP address using commas
#define WIFI_DNS 192,168,2,27 // DNS IP address (might be the same as WIFI_GATEWAY) using commas
#define WIFI_SUBNETMASK 255,255,255,0 // Network mask using commas
#define WIFI_IP_ADDRESS "0.0.0.0" // [IpAddress] Set to 0.0.0.0 for using DHCP or IP address
#define WIFI_GATEWAY "192.168.2.254" // {Gateway] If not using DHCP set Gateway IP address
#define WIFI_SUBNETMASK "255.255.255.0" // [Subnetmask] If not using DHCP set Network mask
#define WIFI_DNS "192.168.2.27" // [DnsServer] If not using DHCP set DNS IP address (might be equal to WIFI_GATEWAY)
#define STA_SSID1 "indebuurt1" // [Ssid1] Wifi SSID
#define STA_PASS1 "VnsqrtnrsddbrN" // [Password1] Wifi password
#define STA_SSID2 "indebuurt2" // [Ssid2] Optional alternate AP Wifi SSID
@ -59,9 +59,9 @@
#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using Chip Id = last 6 characters of MAC address
#define SUB_PREFIX "cmnd" // Sonoff devices subscribe to:- SUB_PREFIX/MQTT_TOPIC and SUB_PREFIX/MQTT_GRPTOPIC
#define PUB_PREFIX "stat" // Sonoff devices publish to:- PUB_PREFIX/MQTT_TOPIC
#define PUB_PREFIX2 "tele" // Sonoff devices publish telemetry data to:- PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER/LIGHT and TIME
#define SUB_PREFIX "cmnd" // [Prefix1] Sonoff devices subscribe to:- SUB_PREFIX/MQTT_TOPIC and SUB_PREFIX/MQTT_GRPTOPIC
#define PUB_PREFIX "stat" // [Prefix2] Sonoff devices publish to:- PUB_PREFIX/MQTT_TOPIC
#define PUB_PREFIX2 "tele" // [Prefix3] Sonoff devices publish telemetry data to:- PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER/LIGHT and TIME
// May be named the same as PUB_PREFIX
#define MQTT_TOPIC PROJECT // [Topic] (unique) MQTT device topic
#define MQTT_GRPTOPIC "sonoffs" // [GroupTopic] MQTT Group topic
@ -83,14 +83,14 @@
#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional)
// -- HTTP ----------------------------------------
#define USE_WEBSERVER // Enable web server and wifi manager (+62k code, +4k mem) - Disable by //
#define WEB_SERVER 2 // [WebServer] Web server (0 = Off, 1 = Start as User, 2 = Start as Admin)
#define WEB_PORT 80 // Web server Port for User and Admin mode
#define WEB_USERNAME "admin" // Web server Admin mode user name
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
#define USE_WEBSERVER // Enable web server and wifi manager (+62k code, +8k mem) - Disable by //
#define WEB_SERVER 2 // [WebServer] Web server (0 = Off, 1 = Start as User, 2 = Start as Admin)
#define WEB_PORT 80 // Web server Port for User and Admin mode
#define WEB_USERNAME "admin" // Web server Admin mode user name
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
#define USE_EMULATION // Enable Belkin WeMo and Hue Bridge emulation for Alexa (+11k code, +2k mem)
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo or Hue Bridge emulation (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo or Hue Bridge emulation (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
// -- mDNS ----------------------------------------
#define USE_DISCOVERY // Enable mDNS for the following services (+8k code, +0.3k mem) - Disable by //

View File

@ -548,22 +548,30 @@ void handleModule()
page += line;
}
page += F("</select></br>");
mytmplt cmodule;
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
String func = F("var os;function sk(s,g){var o=os.replace(\"value='\"+s+\"'\",\"selected value='\"+s+\"'\");document.getElementById('g'+g).innerHTML=o;}function sl(){var o0=\"");
for (byte j = 0; j < GPIO_SENSOR_END; j++) {
snprintf_P(stemp, sizeof(stemp), sensors[j]);
snprintf_P(line, sizeof(line), PSTR("%s'%d'>%02d %s-2"),
(inModule(j, cmodule.gp.io))?"<options disabled value=":"-1", j, j, stemp);
func += line;
}
func += F("\";os=o0.replace(/-1/g,\"<option value=\").replace(/-2/g,\"</option>\");");
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
if (cmodule.gp.io[i] == GPIO_USER) {
snprintf_P(line, sizeof(line), PSTR("<br/><b>GPIO%d</b> %s<select id='g%d' name='g%d'>"),
snprintf_P(line, sizeof(line), PSTR("<br/><b>GPIO%d</b> %s<select id='g%d' name='g%d'></select></br>"),
i, (i==0)?"Button1":(i==1)?"Serial Out":(i==3)?"Serial In":(i==12)?"Relay1":(i==13)?"Led1I":(i==14)?"Sensor":"", i, i);
page += line;
for (byte j = 0; j < GPIO_SENSOR_END; j++) {
snprintf_P(stemp, sizeof(stemp), sensors[j]);
snprintf_P(line, sizeof(line), PSTR("<option%s value='%d'>%02d %s</option>"),
(j == my_module.gp.io[i])?" selected":(inModule(j, cmodule.gp.io))?" disabled":"", j, j, stemp);
page += line;
}
page += F("</select></br>");
snprintf_P(line, sizeof(line), PSTR("sk(%d,%d);"), my_module.gp.io[i], i);
func += line;
}
}
func += F("}</script>");
page.replace("</script>", func);
page.replace("<body>", "<body onload='sl()'>");
page += FPSTR(HTTP_FORM_END);
page += FPSTR(HTTP_BTN_CONF);
showPage(page);
@ -1285,7 +1293,9 @@ void handleInfo()
page += F("<tr><th>Hostname</th><td>"); page += Hostname; page += F("</td></tr>");
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
page += F("<tr><th>IP address</th><td>"); page += WiFi.localIP().toString(); page += F("</td></tr>");
page += F("<tr><th>Gateway</th><td>"); page += WiFi.gatewayIP().toString(); page += F("</td></tr>");
page += F("<tr><th>Gateway</th><td>"); page += IPAddress(sysCfg.ip_address[1]).toString(); page += F("</td></tr>");
page += F("<tr><th>Subnet mask</th><td>"); page += IPAddress(sysCfg.ip_address[2]).toString(); page += F("</td></tr>");
page += F("<tr><th>DNS server</th><td>"); page += IPAddress(sysCfg.ip_address[3]).toString(); page += F("</td></tr>");
page += F("<tr><th>MAC address</th><td>"); page += WiFi.macAddress(); page += F("</td></tr>");
}
if (static_cast<uint32_t>(WiFi.softAPIP()) != 0) {

View File

@ -145,13 +145,13 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
if ((pin[GPIO_WS2812] < 99) && (sysCfg.ws_dimmer == nvalue)) return 1;
if ((sysCfg.module == SONOFF_LED) && (sysCfg.led_dimmer[i] == nvalue)) return 1;
snprintf_P(topicBuf, stopicBuf, PSTR("%s/%s/DIMMER%s"),
SUB_PREFIX, sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp1 : "");
sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic, (Maxdevice > 1) ? stemp1 : "");
snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
found = 1;
} else {
if (((power >> i) &1) == nvalue) return 1;
snprintf_P(topicBuf, stopicBuf, PSTR("%s/%s/%s%s"),
SUB_PREFIX, sysCfg.mqtt_topic, sysCfg.mqtt_subtopic, (Maxdevice > 1) ? stemp1 : "");
sysCfg.mqtt_prefix[0], sysCfg.mqtt_topic, sysCfg.mqtt_subtopic, (Maxdevice > 1) ? stemp1 : "");
snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
found = 1;
}

View File

@ -549,7 +549,7 @@ void hlw_mqttPresent()
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", "), getDateTime().c_str());
hlw_mqttStat(1, svalue, sizeof(svalue));
// snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/ENERGY"), PUB_PREFIX2, sysCfg.mqtt_topic);
// snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/ENERGY"), sysCfg.mqtt_prefix[2], sysCfg.mqtt_topic);
// mqtt_publish(stopic, svalue);
mqtt_publish_topic_P(1, PSTR("ENERGY"), svalue);