3.9.19 20170219
* Sonoff Led: Made GPIO04, 05 and 15 available for user
* Sonoff Led: Add commands Fade, Speed, WakupDuration, Wakeup and
LedTable
This commit is contained in:
arendst 2017-02-19 17:49:17 +01:00
parent 3997f48809
commit 18aaf05622
12 changed files with 1128 additions and 935 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 **3.9.18** - See ```sonoff/_releasenotes.ino``` for change information.
Current version is **3.9.19** - 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.

View File

@ -1,4 +1,8 @@
/* 3.9.18 20170218
/* 3.9.19 20170219
* Sonoff Led: Made GPIO04, 05 and 15 available for user
* Sonoff Led: Add commands Fade, Speed, WakupDuration, Wakeup and LedTable
*
* 3.9.18 20170218
* Fix ledstate 0 to turn off led
* Fix Sonoff Led dimmer range (#16)
* Change Sonoff Led command Dimmer to act on both cold and warm color

188
sonoff/settings.h Normal file
View File

@ -0,0 +1,188 @@
/*********************************************************************************************\
* Config settings
\*********************************************************************************************/
struct SYSCFG2 { // Version 2.x (old)
unsigned long cfg_holder;
unsigned long saveFlag;
unsigned long version;
byte seriallog_level;
byte syslog_level;
char syslog_host[32];
char sta_ssid1[32];
char sta_pwd1[64];
char otaUrl[80];
char mqtt_host[32];
char mqtt_grptopic[32];
char mqtt_topic[32];
char mqtt_topic2[32];
char mqtt_subtopic[32];
int8_t timezone;
uint8_t power;
uint8_t ledstate;
uint16_t mqtt_port;
char mqtt_client[33];
char mqtt_user[33];
char mqtt_pwd[33];
uint8_t webserver;
unsigned long bootcount;
char hostname[33];
uint16_t syslog_port;
byte weblog_level;
uint16_t tele_period;
uint8_t sta_config;
int16_t savedata;
byte model;
byte mqtt_retain;
byte savestate;
unsigned long hlw_pcal;
unsigned long hlw_ucal;
unsigned long hlw_ical;
unsigned long hlw_kWhyesterday;
byte value_units;
uint16_t hlw_pmin;
uint16_t hlw_pmax;
uint16_t hlw_umin;
uint16_t hlw_umax;
uint16_t hlw_imin;
uint16_t hlw_imax;
uint16_t hlw_mpl; // MaxPowerLimit
uint16_t hlw_mplh; // MaxPowerLimitHold
uint16_t hlw_mplw; // MaxPowerLimitWindow
uint16_t hlw_mspl; // MaxSafePowerLimit
uint16_t hlw_msplh; // MaxSafePowerLimitHold
uint16_t hlw_msplw; // MaxSafePowerLimitWindow
uint16_t hlw_mkwh; // MaxEnergy
uint16_t hlw_mkwhs; // MaxEnergyStart
char domoticz_in_topic[33];
char domoticz_out_topic[33];
uint16_t domoticz_update_timer;
unsigned long domoticz_relay_idx[4];
unsigned long domoticz_key_idx[4];
byte message_format; // Not used since 3.2.6a
unsigned long hlw_kWhtoday;
uint16_t hlw_kWhdoy;
uint8_t switchmode;
char mqtt_fingerprint[60];
byte sta_active;
char sta_ssid2[33];
char sta_pwd2[65];
} sysCfg2;
struct SYSCFG {
unsigned long cfg_holder;
unsigned long saveFlag;
unsigned long version;
unsigned long bootcount;
byte migflg;
int16_t savedata;
byte savestate;
byte model;
int8_t timezone;
char otaUrl[101];
char ex_friendlyname[33]; // Not used since 3.2.5 - see below
byte serial_enable;
byte seriallog_level;
uint8_t sta_config;
byte sta_active;
char sta_ssid[2][33];
char sta_pwd[2][65];
char hostname[33];
char syslog_host[33];
uint16_t syslog_port;
byte syslog_level;
uint8_t webserver;
byte weblog_level;
char mqtt_fingerprint[60];
char mqtt_host[33];
uint16_t mqtt_port;
char mqtt_client[33];
char mqtt_user[33];
char mqtt_pwd[33];
char mqtt_topic[33];
char button_topic[33];
char mqtt_grptopic[33];
char mqtt_subtopic[33];
byte mqtt_button_retain;
byte mqtt_power_retain;
byte value_units;
byte message_format; // Not used since 3.2.6a
uint16_t tele_period;
uint8_t power;
uint8_t ledstate;
uint8_t switchmode;
char domoticz_in_topic[33];
char domoticz_out_topic[33];
uint16_t domoticz_update_timer;
unsigned long domoticz_relay_idx[4];
unsigned long domoticz_key_idx[4];
unsigned long hlw_pcal;
unsigned long hlw_ucal;
unsigned long hlw_ical;
unsigned long hlw_kWhtoday;
unsigned long hlw_kWhyesterday;
uint16_t hlw_kWhdoy;
uint16_t hlw_pmin;
uint16_t hlw_pmax;
uint16_t hlw_umin;
uint16_t hlw_umax;
uint16_t hlw_imin;
uint16_t hlw_imax;
uint16_t hlw_mpl; // MaxPowerLimit
uint16_t hlw_mplh; // MaxPowerLimitHold
uint16_t hlw_mplw; // MaxPowerLimitWindow
uint16_t hlw_mspl; // MaxSafePowerLimit
uint16_t hlw_msplh; // MaxSafePowerLimitHold
uint16_t hlw_msplw; // MaxSafePowerLimitWindow
uint16_t hlw_mkwh; // MaxEnergy
uint16_t hlw_mkwhs; // MaxEnergyStart
uint16_t pulsetime;
uint8_t poweronstate;
uint16_t blinktime;
uint16_t blinkcount;
uint16_t ws_pixels;
uint8_t ws_red;
uint8_t ws_green;
uint8_t ws_blue;
uint8_t ws_ledtable;
uint8_t ws_dimmer;
uint8_t ws_fade;
uint8_t ws_speed;
uint8_t ws_scheme;
uint8_t ws_width;
uint16_t ws_wakeup;
char friendlyname[4][33];
char switch_topic[33];
byte mqtt_switch_retain;
uint8_t mqtt_enabled;
uint8_t sleep;
uint16_t domoticz_switch_idx[4];
uint16_t domoticz_sensor_idx[12];
uint8_t module;
mytmplt my_module;
uint16_t led_pixels;
uint8_t led_color[5];
uint8_t led_table;
uint8_t led_dimmer[3];
uint8_t led_fade;
uint8_t led_speed;
uint8_t led_scheme;
uint8_t led_width;
uint16_t led_wakeup;
uint8_t emulation;
} sysCfg;

632
sonoff/settings.ino Normal file
View File

@ -0,0 +1,632 @@
/*
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.
*/
/*********************************************************************************************\
* Config - Flash or Spiffs
\*********************************************************************************************/
extern "C" {
#include "spi_flash.h"
}
#include "eboot_command.h"
#define SPIFFS_START ((uint32_t)&_SPIFFS_start - 0x40200000) / SPI_FLASH_SEC_SIZE
#define SPIFFS_END ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE
// Version 2.x config
#define SPIFFS_CONFIG2 "/config.ini"
#define CFG_LOCATION2 SPIFFS_END - 2
// Version 3.x config
#define SPIFFS_CONFIG "/cfg.ini"
#define CFG_LOCATION SPIFFS_END - 4
uint32_t _cfgHash = 0;
int spiffsflag = 0;
/********************************************************************************************/
/*
* Based on cores/esp8266/Updater.cpp
*/
void setFlashChipMode(byte option, byte mode)
{
char log[LOGSZ];
uint8_t *_buffer;
uint32_t address;
if (option) {
eboot_command ebcmd;
eboot_command_read(&ebcmd);
address = ebcmd.args[0];
} else {
address = 0;
}
_buffer = new uint8_t[FLASH_SECTOR_SIZE];
if (spi_flash_read(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE) == SPI_FLASH_RESULT_OK) {
if (_buffer[2] != mode) {
_buffer[2] = mode &3;
noInterrupts();
if (spi_flash_erase_sector(address / FLASH_SECTOR_SIZE) == SPI_FLASH_RESULT_OK) {
spi_flash_write(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE);
}
interrupts();
snprintf_P(log, sizeof(log), PSTR("FLSH: Updated Flash Chip Mode to %d"), (option) ? mode : ESP.getFlashChipMode());
addLog(LOG_LEVEL_DEBUG, log);
}
}
delete[] _buffer;
}
boolean spiffsPresent()
{
return (SPIFFS_END - SPIFFS_START);
}
uint32_t getHash()
{
uint32_t hash = 0;
uint8_t *bytes = (uint8_t*)&sysCfg;
for (uint16_t i = 0; i < sizeof(SYSCFG); i++) hash += bytes[i]*(i+1);
return hash;
}
/*********************************************************************************************\
* Config Save - Save parameters to Flash or Spiffs ONLY if any parameter has changed
\*********************************************************************************************/
void CFG_Save()
{
char log[LOGSZ];
if ((getHash() != _cfgHash) && (spiffsPresent())) {
if (!spiffsflag) {
#ifdef USE_SPIFFS
sysCfg.saveFlag++;
File f = SPIFFS.open(SPIFFS_CONFIG, "r+");
if (f) {
uint8_t *bytes = (uint8_t*)&sysCfg;
for (int i = 0; i < sizeof(SYSCFG); i++) f.write(bytes[i]);
f.close();
snprintf_P(log, sizeof(log), PSTR("Config: Saved configuration (%d bytes) to spiffs count %d"), sizeof(SYSCFG), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("Config: ERROR - Saving configuration failed"));
}
} else {
#endif // USE_SPIFFS
if (sysCfg.module != SONOFF_LED) noInterrupts();
if (sysCfg.saveFlag == 0) { // Handle default and rollover
spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1));
spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
}
sysCfg.saveFlag++;
spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1));
spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
if (sysCfg.module != SONOFF_LED) interrupts();
snprintf_P(log, sizeof(log), PSTR("Config: Saved configuration (%d bytes) to flash at %X and count %d"), sizeof(SYSCFG), CFG_LOCATION + (sysCfg.saveFlag &1), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
}
_cfgHash = getHash();
}
}
void CFG_Load()
{
char log[LOGSZ];
if (spiffsPresent()) {
if (!spiffsflag) {
#ifdef USE_SPIFFS
File f = SPIFFS.open(SPIFFS_CONFIG, "r+");
if (f) {
uint8_t *bytes = (uint8_t*)&sysCfg;
for (int i = 0; i < sizeof(SYSCFG); i++) bytes[i] = f.read();
f.close();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded configuration from spiffs count %d"), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("Config: ERROR - Loading configuration failed"));
}
} else {
#endif // USE_SPIFFS
struct SYSCFGH {
unsigned long cfg_holder;
unsigned long saveFlag;
} _sysCfgH;
noInterrupts();
spi_flash_read((CFG_LOCATION) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
spi_flash_read((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
if (sysCfg.saveFlag < _sysCfgH.saveFlag)
spi_flash_read((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
interrupts();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded configuration from flash at %X and count %d"), CFG_LOCATION + (sysCfg.saveFlag &1), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
}
}
// snprintf_P(log, sizeof(log), PSTR("Config: Check 1 for migration (%08X)"), sysCfg.version);
// addLog(LOG_LEVEL_NONE, log);
if (sysCfg.cfg_holder != CFG_HOLDER) {
if ((sysCfg.version < 0x03000000) || (sysCfg.version > 0x73000000)) {
CFG_Migrate(); // Config may be present with versions below 3.0.0
} else {
CFG_Default();
}
}
_cfgHash = getHash();
}
void CFG_Migrate()
{
char log[LOGSZ];
if (spiffsPresent()) {
if (!spiffsflag) {
#ifdef USE_SPIFFS
File f = SPIFFS.open(SPIFFS_CONFIG2, "r+");
if (f) {
uint8_t *bytes = (uint8_t*)&sysCfg2;
for (int i = 0; i < sizeof(SYSCFG2); i++) bytes[i] = f.read();
f.close();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded previous configuration from spiffs count %d"), sysCfg2.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("Config: ERROR - Loading previous configuration failed"));
}
} else {
#endif // USE_SPIFFS
struct SYSCFGH {
unsigned long cfg_holder;
unsigned long saveFlag;
} _sysCfgH;
noInterrupts();
spi_flash_read((CFG_LOCATION2) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg2, sizeof(SYSCFG2));
spi_flash_read((CFG_LOCATION2 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
if (sysCfg2.saveFlag < _sysCfgH.saveFlag)
spi_flash_read((CFG_LOCATION2 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg2, sizeof(SYSCFG2));
interrupts();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded previous configuration from flash at %X and count %d"), CFG_LOCATION2 + (sysCfg2.saveFlag &1), sysCfg2.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
}
}
// snprintf_P(log, sizeof(log), PSTR("Config: Check 2 for migration (%08X)"), sysCfg2.version);
// addLog(LOG_LEVEL_NONE, log);
if ((sysCfg2.version > 0x01000000) && (sysCfg2.version < 0x03000000)) {
CFG_Migrate_Part2(); // Config is present between version 1.0.0 and 3.0.0
} else {
CFG_Default();
}
_cfgHash = getHash();
}
void CFG_Erase()
{
char log[LOGSZ];
SpiFlashOpResult result;
uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1;
uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE;
boolean _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level);
snprintf_P(log, sizeof(log), PSTR("Config: Erasing %d flash sectors"), _sectorEnd - _sectorStart);
addLog(LOG_LEVEL_DEBUG, log);
for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) {
noInterrupts();
result = spi_flash_erase_sector(_sector);
interrupts();
if (_serialoutput) {
Serial.print(F("Flash: Erased sector "));
Serial.print(_sector);
if (result == SPI_FLASH_RESULT_OK) {
Serial.println(F(" OK"));
} else {
Serial.println(F(" Error"));
}
delay(10);
}
}
}
void CFG_Dump()
{
#define CFG_COLS 16
char log[LOGSZ];
uint16_t idx, maxrow, row, col;
uint8_t *buffer = (uint8_t *) &sysCfg;
maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS);
for (row = 0; row < maxrow; row++) {
idx = row * CFG_COLS;
snprintf_P(log, sizeof(log), PSTR("%04X:"), idx);
for (col = 0; col < CFG_COLS; col++) {
if (!(col%4)) snprintf_P(log, sizeof(log), PSTR("%s "), log);
snprintf_P(log, sizeof(log), PSTR("%s %02X"), log, buffer[idx + col]);
}
snprintf_P(log, sizeof(log), PSTR("%s |"), log);
for (col = 0; col < CFG_COLS; col++) {
// if (!(col%4)) snprintf_P(log, sizeof(log), PSTR("%s "), log);
snprintf_P(log, sizeof(log), PSTR("%s%c"), log, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' ');
}
snprintf_P(log, sizeof(log), PSTR("%s|"), log);
addLog(LOG_LEVEL_INFO, log);
}
}
#ifdef USE_SPIFFS
void initSpiffs()
{
spiffsflag = 0;
if (!spiffsPresent()) {
spiffsflag = 1;
} else {
if (!SPIFFS.begin()) {
addLog_P(LOG_LEVEL_ERROR, PSTR("SPIFFS: WARNING - Failed to mount file system. Will use flash"));
spiffsflag = 2;
} else {
addLog_P(LOG_LEVEL_DEBUG, PSTR("SPIFFS: Mount successful"));
File f = SPIFFS.open(SPIFFS_CONFIG, "r");
if (!f) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("SPIFFS: Formatting..."));
SPIFFS.format();
addLog_P(LOG_LEVEL_DEBUG, PSTR("SPIFFS: Formatted"));
File f = SPIFFS.open(SPIFFS_CONFIG, "w");
if (f) {
for (int i = 0; i < sizeof(SYSCFG); i++) f.write(0);
f.close();
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("SPIFFS: WARNING - Failed to init config file. Will use flash"));
spiffsflag = 3;
}
}
}
}
}
#endif // USE_SPIFFS
/********************************************************************************************/
void CFG_DefaultSet1()
{
memset(&sysCfg, 0x00, sizeof(SYSCFG));
sysCfg.cfg_holder = CFG_HOLDER;
sysCfg.saveFlag = 0;
sysCfg.version = VERSION;
sysCfg.bootcount = 0;
}
void CFG_DefaultSet2()
{
sysCfg.migflg = 0xA5;
sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE;
sysCfg.module = MODULE;
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;
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]));
strlcpy(sysCfg.sta_pwd[1], STA_PASS2, sizeof(sysCfg.sta_pwd[1]));
strlcpy(sysCfg.hostname, WIFI_HOSTNAME, sizeof(sysCfg.hostname));
sysCfg.sta_config = WIFI_CONFIG_TOOL;
strlcpy(sysCfg.syslog_host, SYS_LOG_HOST, sizeof(sysCfg.syslog_host));
sysCfg.syslog_port = SYS_LOG_PORT;
sysCfg.syslog_level = SYS_LOG_LEVEL;
sysCfg.webserver = WEB_SERVER;
sysCfg.weblog_level = WEB_LOG_LEVEL;
strlcpy(sysCfg.mqtt_fingerprint, MQTT_FINGERPRINT, sizeof(sysCfg.mqtt_fingerprint));
strlcpy(sysCfg.mqtt_host, MQTT_HOST, sizeof(sysCfg.mqtt_host));
sysCfg.mqtt_port = MQTT_PORT;
strlcpy(sysCfg.mqtt_client, MQTT_CLIENT_ID, sizeof(sysCfg.mqtt_client));
strlcpy(sysCfg.mqtt_user, MQTT_USER, sizeof(sysCfg.mqtt_user));
strlcpy(sysCfg.mqtt_pwd, MQTT_PASS, sizeof(sysCfg.mqtt_pwd));
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));
strlcpy(sysCfg.mqtt_subtopic, MQTT_SUBTOPIC, sizeof(sysCfg.mqtt_subtopic));
sysCfg.mqtt_button_retain = MQTT_BUTTON_RETAIN;
sysCfg.mqtt_power_retain = MQTT_POWER_RETAIN;
sysCfg.value_units = VALUE_UNITS;
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;
strlcpy(sysCfg.domoticz_in_topic, DOMOTICZ_IN_TOPIC, sizeof(sysCfg.domoticz_in_topic));
strlcpy(sysCfg.domoticz_out_topic, DOMOTICZ_OUT_TOPIC, sizeof(sysCfg.domoticz_out_topic));
sysCfg.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER;
for (byte i = 0; i < 4; i++) {
sysCfg.domoticz_relay_idx[i] = 0;
sysCfg.domoticz_key_idx[i] = 0;
sysCfg.domoticz_switch_idx[i] = 0;
}
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_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_mplh = MAX_POWER_HOLD;
sysCfg.hlw_mplw = MAX_POWER_WINDOW;
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.ws_pixels = WS2812_LEDS;
sysCfg.ws_red = 255;
sysCfg.ws_green = 0;
sysCfg.ws_blue = 0;
sysCfg.ws_ledtable = 0;
sysCfg.ws_dimmer = 8;
sysCfg.ws_fade = 0;
sysCfg.ws_speed = 1;
sysCfg.ws_scheme = 0;
sysCfg.ws_width = 1;
sysCfg.ws_wakeup = 0;
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]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
sysCfg.led_pixels = 0;
for (byte i = 0; i < 5; i++) sysCfg.led_color[i] = 255;
sysCfg.led_table = 0;
for (byte i = 0; i < 3; i++) sysCfg.led_dimmer[i] = 10;
sysCfg.led_fade = 0;
sysCfg.led_speed = 0;
sysCfg.led_scheme = 0;
sysCfg.led_width = 0;
sysCfg.led_wakeup = 0;
strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic));
sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.mqtt_enabled = MQTT_USE;
sysCfg.emulation = EMULATION;
}
void CFG_Default()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration"));
CFG_DefaultSet1();
CFG_DefaultSet2();
CFG_Save();
}
void CFG_Migrate_Part2()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Migrating configuration"));
CFG_DefaultSet1();
CFG_DefaultSet2();
sysCfg.seriallog_level = sysCfg2.seriallog_level;
sysCfg.syslog_level = sysCfg2.syslog_level;
strlcpy(sysCfg.syslog_host, sysCfg2.syslog_host, sizeof(sysCfg.syslog_host));
strlcpy(sysCfg.sta_ssid[0], sysCfg2.sta_ssid1, sizeof(sysCfg.sta_ssid[0]));
strlcpy(sysCfg.sta_pwd[0], sysCfg2.sta_pwd1, sizeof(sysCfg.sta_pwd[0]));
strlcpy(sysCfg.otaUrl, sysCfg2.otaUrl, sizeof(sysCfg.otaUrl));
strlcpy(sysCfg.mqtt_host, sysCfg2.mqtt_host, sizeof(sysCfg.mqtt_host));
strlcpy(sysCfg.mqtt_grptopic, sysCfg2.mqtt_grptopic, sizeof(sysCfg.mqtt_grptopic));
strlcpy(sysCfg.mqtt_topic, sysCfg2.mqtt_topic, sizeof(sysCfg.mqtt_topic));
strlcpy(sysCfg.button_topic, sysCfg2.mqtt_topic2, sizeof(sysCfg.button_topic));
strlcpy(sysCfg.mqtt_subtopic, sysCfg2.mqtt_subtopic, sizeof(sysCfg.mqtt_subtopic));
sysCfg.timezone = sysCfg2.timezone;
sysCfg.power = sysCfg2.power;
if (sysCfg2.version >= 0x01000D00) { // 1.0.13
sysCfg.ledstate = sysCfg2.ledstate;
}
if (sysCfg2.version >= 0x01001600) { // 1.0.22
sysCfg.mqtt_port = sysCfg2.mqtt_port;
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));
}
if (sysCfg2.version >= 0x01001700) { // 1.0.23
sysCfg.webserver = sysCfg2.webserver;
}
if (sysCfg2.version >= 0x01001A00) { // 1.0.26
sysCfg.bootcount = sysCfg2.bootcount;
strlcpy(sysCfg.hostname, sysCfg2.hostname, sizeof(sysCfg.hostname));
sysCfg.syslog_port = sysCfg2.syslog_port;
}
if (sysCfg2.version >= 0x01001B00) { // 1.0.27
sysCfg.weblog_level = sysCfg2.weblog_level;
}
if (sysCfg2.version >= 0x01001C00) { // 1.0.28
sysCfg.tele_period = sysCfg2.tele_period;
if ((sysCfg.tele_period > 0) && (sysCfg.tele_period < 10)) sysCfg.tele_period = 10; // Do not allow periods < 10 seconds
}
if (sysCfg2.version >= 0x01002000) { // 1.0.32
sysCfg.sta_config = sysCfg2.sta_config;
}
if (sysCfg2.version >= 0x01002300) { // 1.0.35
sysCfg.savedata = sysCfg2.savedata;
}
if (sysCfg2.version >= 0x02000000) { // 2.0.0
sysCfg.model = sysCfg2.model;
}
if (sysCfg2.version >= 0x02000300) { // 2.0.3
sysCfg.mqtt_button_retain = sysCfg2.mqtt_retain;
sysCfg.savestate = sysCfg2.savestate;
}
if (sysCfg2.version >= 0x02000500) { // 2.0.5
sysCfg.hlw_pcal = sysCfg2.hlw_pcal;
sysCfg.hlw_ucal = sysCfg2.hlw_ucal;
sysCfg.hlw_ical = sysCfg2.hlw_ical;
sysCfg.hlw_kWhyesterday = sysCfg2.hlw_kWhyesterday;
sysCfg.value_units = sysCfg2.value_units;
}
if (sysCfg2.version >= 0x02000600) { // 2.0.6
sysCfg.hlw_pmin = sysCfg2.hlw_pmin;
sysCfg.hlw_pmax = sysCfg2.hlw_pmax;
sysCfg.hlw_umin = sysCfg2.hlw_umin;
sysCfg.hlw_umax = sysCfg2.hlw_umax;
sysCfg.hlw_imin = sysCfg2.hlw_imin;
sysCfg.hlw_imax = sysCfg2.hlw_imax;
}
if (sysCfg2.version >= 0x02000700) { // 2.0.7
sysCfg.message_format = 0;
strlcpy(sysCfg.domoticz_in_topic, sysCfg2.domoticz_in_topic, sizeof(sysCfg.domoticz_in_topic));
strlcpy(sysCfg.domoticz_out_topic, sysCfg2.domoticz_out_topic, sizeof(sysCfg.domoticz_out_topic));
sysCfg.domoticz_update_timer = sysCfg2.domoticz_update_timer;
for (byte i = 0; i < 4; i++) {
sysCfg.domoticz_relay_idx[i] = sysCfg2.domoticz_relay_idx[i];
sysCfg.domoticz_key_idx[i] = sysCfg2.domoticz_key_idx[i];
}
sysCfg.hlw_mpl = sysCfg2.hlw_mpl; // MaxPowerLimit
sysCfg.hlw_mplh = sysCfg2.hlw_mplh;
sysCfg.hlw_mplw = sysCfg2.hlw_mplw;
sysCfg.hlw_mspl = sysCfg2.hlw_mspl; // MaxSafePowerLimit
sysCfg.hlw_msplh = sysCfg2.hlw_msplh;
sysCfg.hlw_msplw = sysCfg2.hlw_msplw;
sysCfg.hlw_mkwh = sysCfg2.hlw_mkwh; // MaxEnergy
sysCfg.hlw_mkwhs = sysCfg2.hlw_mkwhs; // MaxEnergyStart
}
if (sysCfg2.version >= 0x02001000) { // 2.0.16
sysCfg.hlw_kWhtoday = sysCfg2.hlw_kWhtoday;
sysCfg.hlw_kWhdoy = sysCfg2.hlw_kWhdoy;
}
if (sysCfg2.version >= 0x02001200) { // 2.0.18
sysCfg.switchmode = sysCfg2.switchmode;
}
if (sysCfg2.version >= 0x02010000) { // 2.1.0
strlcpy(sysCfg.mqtt_fingerprint, sysCfg2.mqtt_fingerprint, sizeof(sysCfg.mqtt_fingerprint));
}
if (sysCfg2.version >= 0x02010200) { // 2.1.2
sysCfg.sta_active = sysCfg2.sta_active;
strlcpy(sysCfg.sta_ssid[1], sysCfg2.sta_ssid2, sizeof(sysCfg.sta_ssid[1]));
strlcpy(sysCfg.sta_pwd[1], sysCfg2.sta_pwd2, sizeof(sysCfg.sta_pwd[1]));
}
CFG_Save();
}
/********************************************************************************************/
void CFG_Delta()
{
if (sysCfg.version != VERSION) { // Fix version dependent changes
if (sysCfg.version < 0x03000600) { // 3.0.6 - Add parameter
sysCfg.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;
}
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.ex_friendlyname, sysCfg.mqtt_client, sizeof(sysCfg.ex_friendlyname));
}
if (sysCfg.version < 0x03020400) { // 3.2.4 - Add parameter
sysCfg.ws_pixels = WS2812_LEDS;
sysCfg.ws_red = 255;
sysCfg.ws_green = 0;
sysCfg.ws_blue = 0;
sysCfg.ws_ledtable = 0;
sysCfg.ws_dimmer = 8;
sysCfg.ws_fade = 0;
sysCfg.ws_speed = 1;
sysCfg.ws_scheme = 0;
sysCfg.ws_width = 1;
sysCfg.ws_wakeup = 0;
}
if (sysCfg.version < 0x03020500) { // 3.2.5 - Add parameter
strlcpy(sysCfg.friendlyname[0], sysCfg.ex_friendlyname, 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]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
}
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;
}
if (sysCfg.version < 0x03020C00) { // 3.2.12 - Add parameter
sysCfg.sleep = APP_SLEEP;
}
if (sysCfg.version < 0x03090204) { // 3.9.2d - Add parameter
for (byte i = 0; i < 4; i++) sysCfg.domoticz_switch_idx[i] = 0;
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_idx[i] = 0;
sysCfg.module = MODULE;
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
sysCfg.led_pixels = 0;
for (byte i = 0; i < 5; i++) sysCfg.led_color[i] = 255;
sysCfg.led_table = 0;
for (byte i = 0; i < 3; i++) sysCfg.led_dimmer[i] = 10;
sysCfg.led_fade = 0;
sysCfg.led_speed = 0;
sysCfg.led_scheme = 0;
sysCfg.led_width = 0;
sysCfg.led_wakeup = 0;
}
if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter
sysCfg.emulation = EMULATION;
}
sysCfg.version = VERSION;
}
}

View File

@ -10,7 +10,7 @@
* ====================================================
*/
#define VERSION 0x03091200 // 3.9.18
#define VERSION 0x03091300 // 3.9.19
//#define BE_MINIMAL // Compile a minimal version if upgrade memory gets tight (still 404k)
// To be used as step 1. Next step is compile and use desired version
@ -155,6 +155,7 @@ enum butt_t {PRESSED, NOT_PRESSED};
#ifdef USE_I2C
#include <Wire.h> // I2C support library
#endif // USE_I2C
#include "settings.h"
typedef void (*rtcCallback)();
@ -171,190 +172,6 @@ const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = {
const char wificfg[5][12] PROGMEM = { "Restart", "Smartconfig", "Wifimanager", "WPSconfig", "Retry" };
struct SYSCFG2 { // Version 2.x (old)
unsigned long cfg_holder;
unsigned long saveFlag;
unsigned long version;
byte seriallog_level;
byte syslog_level;
char syslog_host[32];
char sta_ssid1[32];
char sta_pwd1[64];
char otaUrl[80];
char mqtt_host[32];
char mqtt_grptopic[32];
char mqtt_topic[32];
char mqtt_topic2[32];
char mqtt_subtopic[32];
int8_t timezone;
uint8_t power;
uint8_t ledstate;
uint16_t mqtt_port;
char mqtt_client[33];
char mqtt_user[33];
char mqtt_pwd[33];
uint8_t webserver;
unsigned long bootcount;
char hostname[33];
uint16_t syslog_port;
byte weblog_level;
uint16_t tele_period;
uint8_t sta_config;
int16_t savedata;
byte model;
byte mqtt_retain;
byte savestate;
unsigned long hlw_pcal;
unsigned long hlw_ucal;
unsigned long hlw_ical;
unsigned long hlw_kWhyesterday;
byte value_units;
uint16_t hlw_pmin;
uint16_t hlw_pmax;
uint16_t hlw_umin;
uint16_t hlw_umax;
uint16_t hlw_imin;
uint16_t hlw_imax;
uint16_t hlw_mpl; // MaxPowerLimit
uint16_t hlw_mplh; // MaxPowerLimitHold
uint16_t hlw_mplw; // MaxPowerLimitWindow
uint16_t hlw_mspl; // MaxSafePowerLimit
uint16_t hlw_msplh; // MaxSafePowerLimitHold
uint16_t hlw_msplw; // MaxSafePowerLimitWindow
uint16_t hlw_mkwh; // MaxEnergy
uint16_t hlw_mkwhs; // MaxEnergyStart
char domoticz_in_topic[33];
char domoticz_out_topic[33];
uint16_t domoticz_update_timer;
unsigned long domoticz_relay_idx[4];
unsigned long domoticz_key_idx[4];
byte message_format; // Not used since 3.2.6a
unsigned long hlw_kWhtoday;
uint16_t hlw_kWhdoy;
uint8_t switchmode;
char mqtt_fingerprint[60];
byte sta_active;
char sta_ssid2[33];
char sta_pwd2[65];
} sysCfg2;
struct SYSCFG {
unsigned long cfg_holder;
unsigned long saveFlag;
unsigned long version;
unsigned long bootcount;
byte migflg;
int16_t savedata;
byte savestate;
byte model;
int8_t timezone;
char otaUrl[101];
char ex_friendlyname[33]; // Not used since 3.2.5 - see below
byte serial_enable;
byte seriallog_level;
uint8_t sta_config;
byte sta_active;
char sta_ssid[2][33];
char sta_pwd[2][65];
char hostname[33];
char syslog_host[33];
uint16_t syslog_port;
byte syslog_level;
uint8_t webserver;
byte weblog_level;
char mqtt_fingerprint[60];
char mqtt_host[33];
uint16_t mqtt_port;
char mqtt_client[33];
char mqtt_user[33];
char mqtt_pwd[33];
char mqtt_topic[33];
char button_topic[33];
char mqtt_grptopic[33];
char mqtt_subtopic[33];
byte mqtt_button_retain;
byte mqtt_power_retain;
byte value_units;
byte message_format; // Not used since 3.2.6a
uint16_t tele_period;
uint8_t power;
uint8_t ledstate;
uint8_t switchmode;
char domoticz_in_topic[33];
char domoticz_out_topic[33];
uint16_t domoticz_update_timer;
unsigned long domoticz_relay_idx[4];
unsigned long domoticz_key_idx[4];
unsigned long hlw_pcal;
unsigned long hlw_ucal;
unsigned long hlw_ical;
unsigned long hlw_kWhtoday;
unsigned long hlw_kWhyesterday;
uint16_t hlw_kWhdoy;
uint16_t hlw_pmin;
uint16_t hlw_pmax;
uint16_t hlw_umin;
uint16_t hlw_umax;
uint16_t hlw_imin;
uint16_t hlw_imax;
uint16_t hlw_mpl; // MaxPowerLimit
uint16_t hlw_mplh; // MaxPowerLimitHold
uint16_t hlw_mplw; // MaxPowerLimitWindow
uint16_t hlw_mspl; // MaxSafePowerLimit
uint16_t hlw_msplh; // MaxSafePowerLimitHold
uint16_t hlw_msplw; // MaxSafePowerLimitWindow
uint16_t hlw_mkwh; // MaxEnergy
uint16_t hlw_mkwhs; // MaxEnergyStart
uint16_t pulsetime;
uint8_t poweronstate;
uint16_t blinktime;
uint16_t blinkcount;
uint16_t ws_pixels;
uint8_t ws_red;
uint8_t ws_green;
uint8_t ws_blue;
uint8_t ws_ledtable;
uint8_t ws_dimmer;
uint8_t ws_fade;
uint8_t ws_speed;
uint8_t ws_scheme;
uint8_t ws_width;
uint16_t ws_wakeup;
char friendlyname[4][33];
char switch_topic[33];
byte mqtt_switch_retain;
uint8_t mqtt_enabled;
uint8_t sleep;
uint16_t domoticz_switch_idx[4];
uint16_t domoticz_sensor_idx[12];
uint8_t module;
mytmplt my_module;
uint16_t led_pixels;
uint8_t led_color[5];
uint8_t led_table;
uint8_t led_dimmer[3];
uint8_t led_fade;
uint8_t led_speed;
uint8_t led_scheme;
uint8_t led_width;
uint16_t led_wakeup;
uint8_t emulation;
} sysCfg;
struct TIME_T {
uint8_t Second;
uint8_t Minute;
@ -451,324 +268,6 @@ boolean mDNSbegun = false;
/********************************************************************************************/
void CFG_DefaultSet1()
{
memset(&sysCfg, 0x00, sizeof(SYSCFG));
sysCfg.cfg_holder = CFG_HOLDER;
sysCfg.saveFlag = 0;
sysCfg.version = VERSION;
sysCfg.bootcount = 0;
}
void CFG_DefaultSet2()
{
sysCfg.migflg = 0xA5;
sysCfg.savedata = SAVE_DATA;
sysCfg.savestate = SAVE_STATE;
sysCfg.module = MODULE;
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;
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]));
strlcpy(sysCfg.sta_pwd[1], STA_PASS2, sizeof(sysCfg.sta_pwd[1]));
strlcpy(sysCfg.hostname, WIFI_HOSTNAME, sizeof(sysCfg.hostname));
sysCfg.sta_config = WIFI_CONFIG_TOOL;
strlcpy(sysCfg.syslog_host, SYS_LOG_HOST, sizeof(sysCfg.syslog_host));
sysCfg.syslog_port = SYS_LOG_PORT;
sysCfg.syslog_level = SYS_LOG_LEVEL;
sysCfg.webserver = WEB_SERVER;
sysCfg.weblog_level = WEB_LOG_LEVEL;
strlcpy(sysCfg.mqtt_fingerprint, MQTT_FINGERPRINT, sizeof(sysCfg.mqtt_fingerprint));
strlcpy(sysCfg.mqtt_host, MQTT_HOST, sizeof(sysCfg.mqtt_host));
sysCfg.mqtt_port = MQTT_PORT;
strlcpy(sysCfg.mqtt_client, MQTT_CLIENT_ID, sizeof(sysCfg.mqtt_client));
strlcpy(sysCfg.mqtt_user, MQTT_USER, sizeof(sysCfg.mqtt_user));
strlcpy(sysCfg.mqtt_pwd, MQTT_PASS, sizeof(sysCfg.mqtt_pwd));
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));
strlcpy(sysCfg.mqtt_subtopic, MQTT_SUBTOPIC, sizeof(sysCfg.mqtt_subtopic));
sysCfg.mqtt_button_retain = MQTT_BUTTON_RETAIN;
sysCfg.mqtt_power_retain = MQTT_POWER_RETAIN;
sysCfg.value_units = VALUE_UNITS;
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;
strlcpy(sysCfg.domoticz_in_topic, DOMOTICZ_IN_TOPIC, sizeof(sysCfg.domoticz_in_topic));
strlcpy(sysCfg.domoticz_out_topic, DOMOTICZ_OUT_TOPIC, sizeof(sysCfg.domoticz_out_topic));
sysCfg.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER;
for (byte i = 0; i < 4; i++) {
sysCfg.domoticz_relay_idx[i] = 0;
sysCfg.domoticz_key_idx[i] = 0;
sysCfg.domoticz_switch_idx[i] = 0;
}
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_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_mplh = MAX_POWER_HOLD;
sysCfg.hlw_mplw = MAX_POWER_WINDOW;
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.ws_pixels = WS2812_LEDS;
sysCfg.ws_red = 255;
sysCfg.ws_green = 0;
sysCfg.ws_blue = 0;
sysCfg.ws_ledtable = 0;
sysCfg.ws_dimmer = 8;
sysCfg.ws_fade = 0;
sysCfg.ws_speed = 1;
sysCfg.ws_scheme = 0;
sysCfg.ws_width = 1;
sysCfg.ws_wakeup = 0;
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]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
sysCfg.led_pixels = 0;
for (byte i = 0; i < 5; i++) sysCfg.led_color[i] = 255;
sysCfg.led_table = 0;
for (byte i = 0; i < 3; i++) sysCfg.led_dimmer[i] = 10;
sysCfg.led_fade = 0;
sysCfg.led_speed = 0;
sysCfg.led_scheme = 0;
sysCfg.led_width = 0;
sysCfg.led_wakeup = 0;
strlcpy(sysCfg.switch_topic, "0", sizeof(sysCfg.switch_topic));
sysCfg.mqtt_switch_retain = MQTT_SWITCH_RETAIN;
sysCfg.mqtt_enabled = MQTT_USE;
sysCfg.emulation = EMULATION;
}
void CFG_Default()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Use default configuration"));
CFG_DefaultSet1();
CFG_DefaultSet2();
CFG_Save();
}
void CFG_Migrate_Part2()
{
addLog_P(LOG_LEVEL_NONE, PSTR("Config: Migrating configuration"));
CFG_DefaultSet1();
CFG_DefaultSet2();
sysCfg.seriallog_level = sysCfg2.seriallog_level;
sysCfg.syslog_level = sysCfg2.syslog_level;
strlcpy(sysCfg.syslog_host, sysCfg2.syslog_host, sizeof(sysCfg.syslog_host));
strlcpy(sysCfg.sta_ssid[0], sysCfg2.sta_ssid1, sizeof(sysCfg.sta_ssid[0]));
strlcpy(sysCfg.sta_pwd[0], sysCfg2.sta_pwd1, sizeof(sysCfg.sta_pwd[0]));
strlcpy(sysCfg.otaUrl, sysCfg2.otaUrl, sizeof(sysCfg.otaUrl));
strlcpy(sysCfg.mqtt_host, sysCfg2.mqtt_host, sizeof(sysCfg.mqtt_host));
strlcpy(sysCfg.mqtt_grptopic, sysCfg2.mqtt_grptopic, sizeof(sysCfg.mqtt_grptopic));
strlcpy(sysCfg.mqtt_topic, sysCfg2.mqtt_topic, sizeof(sysCfg.mqtt_topic));
strlcpy(sysCfg.button_topic, sysCfg2.mqtt_topic2, sizeof(sysCfg.button_topic));
strlcpy(sysCfg.mqtt_subtopic, sysCfg2.mqtt_subtopic, sizeof(sysCfg.mqtt_subtopic));
sysCfg.timezone = sysCfg2.timezone;
sysCfg.power = sysCfg2.power;
if (sysCfg2.version >= 0x01000D00) { // 1.0.13
sysCfg.ledstate = sysCfg2.ledstate;
}
if (sysCfg2.version >= 0x01001600) { // 1.0.22
sysCfg.mqtt_port = sysCfg2.mqtt_port;
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));
}
if (sysCfg2.version >= 0x01001700) { // 1.0.23
sysCfg.webserver = sysCfg2.webserver;
}
if (sysCfg2.version >= 0x01001A00) { // 1.0.26
sysCfg.bootcount = sysCfg2.bootcount;
strlcpy(sysCfg.hostname, sysCfg2.hostname, sizeof(sysCfg.hostname));
sysCfg.syslog_port = sysCfg2.syslog_port;
}
if (sysCfg2.version >= 0x01001B00) { // 1.0.27
sysCfg.weblog_level = sysCfg2.weblog_level;
}
if (sysCfg2.version >= 0x01001C00) { // 1.0.28
sysCfg.tele_period = sysCfg2.tele_period;
if ((sysCfg.tele_period > 0) && (sysCfg.tele_period < 10)) sysCfg.tele_period = 10; // Do not allow periods < 10 seconds
}
if (sysCfg2.version >= 0x01002000) { // 1.0.32
sysCfg.sta_config = sysCfg2.sta_config;
}
if (sysCfg2.version >= 0x01002300) { // 1.0.35
sysCfg.savedata = sysCfg2.savedata;
}
if (sysCfg2.version >= 0x02000000) { // 2.0.0
sysCfg.model = sysCfg2.model;
}
if (sysCfg2.version >= 0x02000300) { // 2.0.3
sysCfg.mqtt_button_retain = sysCfg2.mqtt_retain;
sysCfg.savestate = sysCfg2.savestate;
}
if (sysCfg2.version >= 0x02000500) { // 2.0.5
sysCfg.hlw_pcal = sysCfg2.hlw_pcal;
sysCfg.hlw_ucal = sysCfg2.hlw_ucal;
sysCfg.hlw_ical = sysCfg2.hlw_ical;
sysCfg.hlw_kWhyesterday = sysCfg2.hlw_kWhyesterday;
sysCfg.value_units = sysCfg2.value_units;
}
if (sysCfg2.version >= 0x02000600) { // 2.0.6
sysCfg.hlw_pmin = sysCfg2.hlw_pmin;
sysCfg.hlw_pmax = sysCfg2.hlw_pmax;
sysCfg.hlw_umin = sysCfg2.hlw_umin;
sysCfg.hlw_umax = sysCfg2.hlw_umax;
sysCfg.hlw_imin = sysCfg2.hlw_imin;
sysCfg.hlw_imax = sysCfg2.hlw_imax;
}
if (sysCfg2.version >= 0x02000700) { // 2.0.7
sysCfg.message_format = 0;
strlcpy(sysCfg.domoticz_in_topic, sysCfg2.domoticz_in_topic, sizeof(sysCfg.domoticz_in_topic));
strlcpy(sysCfg.domoticz_out_topic, sysCfg2.domoticz_out_topic, sizeof(sysCfg.domoticz_out_topic));
sysCfg.domoticz_update_timer = sysCfg2.domoticz_update_timer;
for (byte i = 0; i < 4; i++) {
sysCfg.domoticz_relay_idx[i] = sysCfg2.domoticz_relay_idx[i];
sysCfg.domoticz_key_idx[i] = sysCfg2.domoticz_key_idx[i];
}
sysCfg.hlw_mpl = sysCfg2.hlw_mpl; // MaxPowerLimit
sysCfg.hlw_mplh = sysCfg2.hlw_mplh;
sysCfg.hlw_mplw = sysCfg2.hlw_mplw;
sysCfg.hlw_mspl = sysCfg2.hlw_mspl; // MaxSafePowerLimit
sysCfg.hlw_msplh = sysCfg2.hlw_msplh;
sysCfg.hlw_msplw = sysCfg2.hlw_msplw;
sysCfg.hlw_mkwh = sysCfg2.hlw_mkwh; // MaxEnergy
sysCfg.hlw_mkwhs = sysCfg2.hlw_mkwhs; // MaxEnergyStart
}
if (sysCfg2.version >= 0x02001000) { // 2.0.16
sysCfg.hlw_kWhtoday = sysCfg2.hlw_kWhtoday;
sysCfg.hlw_kWhdoy = sysCfg2.hlw_kWhdoy;
}
if (sysCfg2.version >= 0x02001200) { // 2.0.18
sysCfg.switchmode = sysCfg2.switchmode;
}
if (sysCfg2.version >= 0x02010000) { // 2.1.0
strlcpy(sysCfg.mqtt_fingerprint, sysCfg2.mqtt_fingerprint, sizeof(sysCfg.mqtt_fingerprint));
}
if (sysCfg2.version >= 0x02010200) { // 2.1.2
sysCfg.sta_active = sysCfg2.sta_active;
strlcpy(sysCfg.sta_ssid[1], sysCfg2.sta_ssid2, sizeof(sysCfg.sta_ssid[1]));
strlcpy(sysCfg.sta_pwd[1], sysCfg2.sta_pwd2, sizeof(sysCfg.sta_pwd[1]));
}
CFG_Save();
}
void CFG_Delta()
{
if (sysCfg.version != VERSION) { // Fix version dependent changes
if (sysCfg.version < 0x03000600) { // 3.0.6 - Add parameter
sysCfg.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;
}
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.ex_friendlyname, sysCfg.mqtt_client, sizeof(sysCfg.ex_friendlyname));
}
if (sysCfg.version < 0x03020400) { // 3.2.4 - Add parameter
sysCfg.ws_pixels = WS2812_LEDS;
sysCfg.ws_red = 255;
sysCfg.ws_green = 0;
sysCfg.ws_blue = 0;
sysCfg.ws_ledtable = 0;
sysCfg.ws_dimmer = 8;
sysCfg.ws_fade = 0;
sysCfg.ws_speed = 1;
sysCfg.ws_scheme = 0;
sysCfg.ws_width = 1;
sysCfg.ws_wakeup = 0;
}
if (sysCfg.version < 0x03020500) { // 3.2.5 - Add parameter
strlcpy(sysCfg.friendlyname[0], sysCfg.ex_friendlyname, 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]));
strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
}
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;
}
if (sysCfg.version < 0x03020C00) { // 3.2.12 - Add parameter
sysCfg.sleep = APP_SLEEP;
}
if (sysCfg.version < 0x03090204) { // 3.9.2d - Add parameter
for (byte i = 0; i < 4; i++) sysCfg.domoticz_switch_idx[i] = 0;
for (byte i = 0; i < 12; i++) sysCfg.domoticz_sensor_idx[i] = 0;
sysCfg.module = MODULE;
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
sysCfg.led_pixels = 0;
for (byte i = 0; i < 5; i++) sysCfg.led_color[i] = 255;
sysCfg.led_table = 0;
for (byte i = 0; i < 3; i++) sysCfg.led_dimmer[i] = 10;
sysCfg.led_fade = 0;
sysCfg.led_speed = 0;
sysCfg.led_scheme = 0;
sysCfg.led_width = 0;
sysCfg.led_wakeup = 0;
}
if (sysCfg.version < 0x03090700) { // 3.9.7 - Add parameter
sysCfg.emulation = EMULATION;
}
sysCfg.version = VERSION;
}
}
/********************************************************************************************/
void getClient(char* output, const char* input, byte size)
{
char *token;
@ -821,7 +320,7 @@ void setRelay(uint8_t power)
Serial.flush();
}
else if (sysCfg.module == SONOFF_LED) {
sl_setColor(power &1);
sl_setPower(power &1);
}
else if (sysCfg.module == EXS_RELAY) {
setLatchingRelay(power, 1);
@ -844,68 +343,6 @@ void setLed(uint8_t state)
/********************************************************************************************/
void sl_setDim(uint8_t *my_color)
{
float newDim, fmyCld, fmyWrm, fmyRed, fmyGrn, fmyBlu;
newDim = 100 / (float)sysCfg.led_dimmer[0];
fmyCld = (float)sysCfg.led_color[0] / newDim;
fmyWrm = (float)sysCfg.led_color[1] / newDim;
fmyRed = (float)sysCfg.led_color[2] / newDim;
fmyGrn = (float)sysCfg.led_color[3] / newDim;
fmyBlu = (float)sysCfg.led_color[4] / newDim;
my_color[0] = (uint8_t)fmyCld;
my_color[1] = (uint8_t)fmyWrm;
my_color[2] = (uint8_t)fmyRed;
my_color[3] = (uint8_t)fmyGrn;
my_color[4] = (uint8_t)fmyBlu;
}
void sl_setColor(byte type)
{
// 0 = Off
// 1 = On
// 2 = Dim cold/warm
// 3 = Dim color
uint8_t my_color[5];
sl_setDim(my_color);
if (type == 0) {
for (byte i = 0; i < 5; i++) {
if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], 0);
}
}
else if (type == 1) {
for (byte i = 0; i < 5; i++) {
if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], my_color[i]);
}
}
else if (type == 2) { // Cold/Warm
for (byte i = 0; i < 2; i++) {
if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], my_color[i]);
}
}
else if (type == 3) { // Color
for (byte i = 2; i < 5; i++) {
if (pin[GPIO_PWM0 +i] < 99) analogWrite(pin[GPIO_PWM0 +i], my_color[i]);
}
}
}
void sl_blank(byte state)
{
if (sysCfg.module == SONOFF_LED) {
if (state) {
if (power &1) sl_setColor(1);
} else {
sl_setColor(0);
}
}
}
/********************************************************************************************/
void json2legacy(char* stopic, char* svalue)
{
char *p, *token;
@ -951,24 +388,6 @@ void json2legacy(char* stopic, char* svalue)
}
}
uint32_t Atoh(char *s)
{
uint32_t value = 0, digit;
int8_t c;
while((c = *s++)){
if('0' <= c && c <= '9')
digit = c - '0';
else if('A' <= c && c <= 'F')
digit = c - 'A' + 10;
else if('a' <= c && c<= 'f')
digit = c - 'a' + 10;
else break;
value = (value << 4) | digit;
}
return value;
}
/********************************************************************************************/
void mqtt_publish_sec(const char* topic, const char* data, boolean retained)
@ -1150,6 +569,8 @@ void mqtt_reconnect()
}
}
/********************************************************************************************/
void mqttDataCb(char* topic, byte* data, unsigned int data_len)
{
char *str;
@ -1262,53 +683,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"BlinkCount\":%d}"), sysCfg.blinkcount);
}
/*** Sonoff Led Commands *********************************************************************/
else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"COLOR")) {
uint8_t my_color[5];
if (data_len == 4) {
char ccold[3], cwarm[3];
memcpy(ccold, dataBufUc, 2);
ccold[2] = '\0';
memcpy(cwarm, dataBufUc + 2, 2);
cwarm[2] = '\0';
my_color[0] = Atoh(ccold);
my_color[1] = Atoh(cwarm);
uint16_t temp = my_color[0];
if (temp < my_color[1]) temp = my_color[1];
float mDim = (float)temp / 2.55;
sysCfg.led_dimmer[0] = (uint8_t)mDim;
float newDim = 100 / mDim;
float fmyCold = (float)my_color[0] * newDim;
float fmyWarm = (float)my_color[1] * newDim;
sysCfg.led_color[0] = (uint8_t)fmyCold;
sysCfg.led_color[1] = (uint8_t)fmyWarm;
power = 1;
#ifdef USE_DOMOTICZ
mqtt_publishDomoticzPowerState(index);
#endif // USE_DOMOTICZ
sl_setColor(2);
else if ((sysCfg.module == SONOFF_LED) && sl_command(type, index, dataBufUc, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
sl_setDim(my_color);
uint16_t color = (uint16_t)my_color[0] << 8;
color += (uint16_t)my_color[1];
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Color\":\"%04X\"}"), color);
}
else if ((sysCfg.module == SONOFF_LED) && !strcmp(type,"DIMMER")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 100)) {
sysCfg.led_dimmer[0] = payload;
power = 1;
#ifdef USE_DOMOTICZ
mqtt_publishDomoticzPowerState(index);
#endif // USE_DOMOTICZ
sl_setColor(2);
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Dimmer\":%d}"), sysCfg.led_dimmer[0]);
}
/*********************************************************************************************/
else if (!strcmp(type,"SAVEDATA")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 3600)) {
sysCfg.savedata = payload;
@ -1803,8 +1180,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
#ifdef USE_I2C
if (i2c_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, I2CScan"), svalue);
#endif // USE_I2C
if (sysCfg.module == SONOFF_LED) snprintf_P(svalue, sizeof(svalue), PSTR("%s, Color, Dimmer, Fade, Speed, Wakeup, WakeupDuration, LedTable"), svalue);
#ifdef USE_WS2812
if (pin[GPIO_WS2812] < 99) snprintf_P(svalue, sizeof(svalue), PSTR("%s, Pixels, Led, Color, Dimmer, Scheme, Fade, Speed, Width, Wakeup, LedTable"), svalue);
if (pin[GPIO_WS2812] < 99) snprintf_P(svalue, sizeof(svalue), PSTR("%s, Color, Dimmer, Fade, Speed, Wakeup, LedTable, Pixels, Led, Width, Scheme"), svalue);
#endif
#ifdef USE_IR_REMOTE
if (pin[GPIO_IRSEND] < 99) snprintf_P(svalue, sizeof(svalue), PSTR("%s, IRSend"), svalue);
@ -2211,6 +1589,8 @@ void stateloop()
}
}
if (sysCfg.module == SONOFF_LED) sl_animate();
#ifdef USE_WS2812
if (pin[GPIO_WS2812] < 99) ws2812_animate();
#endif // USE_WS2812
@ -2343,7 +1723,7 @@ void stateloop()
if (otaflag <= 0) {
otaflag = 12;
ESPhttpUpdate.rebootOnUpdate(false);
sl_blank(0);
sl_blank(1);
// Try multiple times to get the update, in case we have a transient issue.
// e.g. Someone issued "cmnd/sonoffs/update 1" and all the devices
// are hammering the OTAURL.
@ -2361,7 +1741,7 @@ void stateloop()
snprintf_P(svalue, sizeof(svalue), PSTR("Successful. Restarting"));
restartflag = 2;
} else {
sl_blank(1);
sl_blank(0);
snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str());
}
mqtt_publish_topic_P(0, PSTR("UPGRADE"), svalue);
@ -2536,11 +1916,8 @@ void GPIO_init()
Baudrate = 19200;
}
else if (sysCfg.module == SONOFF_LED) {
analogWriteRange(255); // Default is 1023 (Arduino.h)
analogWriteFreq(200); // Default is 1000 (core_esp8266_wiring_pwm.c) - Try to lower flicker
for (byte i = 0; i < 5; i++) {
if (pin[GPIO_PWM0 +i] < 99) pinMode(pin[GPIO_PWM0 +i], OUTPUT);
}
pin[GPIO_WS2812] = 99; // I do not allow both Sonoff Led AND WS2812 led
sl_init();
}
else {
for (byte i = 0; i < 4; i++) {

View File

@ -212,13 +212,13 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
{ "Sonoff LED", // Sonoff LED
GPIO_KEY1, // GPIO00 Button
0, 0, 0,
GPIO_PWM3, // GPIO04 Green light
GPIO_PWM2, // GPIO05 Red light
GPIO_USER, // GPIO04 Optional sensor (PWM3 Green)
GPIO_USER, // GPIO05 Optional sensor (PWM2 Red)
0, 0, 0, 0, 0, 0,
GPIO_PWM0, // GPIO12 Cold light
GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off)
GPIO_PWM1, // GPIO14 Warm light
GPIO_PWM4, // GPIO15 Blue light
GPIO_USER, // GPIO15 Optional sensor (PWM4 Blue)
0
},
{ "1 Channel", // 1 Channel Inching/Latching Relay

View File

@ -23,292 +23,6 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*********************************************************************************************\
* Config - Flash or Spiffs
\*********************************************************************************************/
extern "C" {
#include "spi_flash.h"
}
#define SPIFFS_START ((uint32_t)&_SPIFFS_start - 0x40200000) / SPI_FLASH_SEC_SIZE
#define SPIFFS_END ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE
// Version 2.x config
#define SPIFFS_CONFIG2 "/config.ini"
#define CFG_LOCATION2 SPIFFS_END - 2
// Version 3.x config
#define SPIFFS_CONFIG "/cfg.ini"
#define CFG_LOCATION SPIFFS_END - 4
uint32_t _cfgHash = 0;
int spiffsflag = 0;
boolean spiffsPresent()
{
return (SPIFFS_END - SPIFFS_START);
}
uint32_t getHash()
{
uint32_t hash = 0;
uint8_t *bytes = (uint8_t*)&sysCfg;
for (uint16_t i = 0; i < sizeof(SYSCFG); i++) hash += bytes[i]*(i+1);
return hash;
}
/*********************************************************************************************\
* Config Save - Save parameters to Flash or Spiffs ONLY if any parameter has changed
\*********************************************************************************************/
void CFG_Save()
{
char log[LOGSZ];
if ((getHash() != _cfgHash) && (spiffsPresent())) {
if (!spiffsflag) {
#ifdef USE_SPIFFS
sysCfg.saveFlag++;
File f = SPIFFS.open(SPIFFS_CONFIG, "r+");
if (f) {
uint8_t *bytes = (uint8_t*)&sysCfg;
for (int i = 0; i < sizeof(SYSCFG); i++) f.write(bytes[i]);
f.close();
snprintf_P(log, sizeof(log), PSTR("Config: Saved configuration (%d bytes) to spiffs count %d"), sizeof(SYSCFG), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("Config: ERROR - Saving configuration failed"));
}
} else {
#endif // USE_SPIFFS
if (sysCfg.module != SONOFF_LED) noInterrupts();
if (sysCfg.saveFlag == 0) { // Handle default and rollover
spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1));
spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
}
sysCfg.saveFlag++;
spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1));
spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
if (sysCfg.module != SONOFF_LED) interrupts();
snprintf_P(log, sizeof(log), PSTR("Config: Saved configuration (%d bytes) to flash at %X and count %d"), sizeof(SYSCFG), CFG_LOCATION + (sysCfg.saveFlag &1), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
}
_cfgHash = getHash();
}
}
void CFG_Load()
{
char log[LOGSZ];
if (spiffsPresent()) {
if (!spiffsflag) {
#ifdef USE_SPIFFS
File f = SPIFFS.open(SPIFFS_CONFIG, "r+");
if (f) {
uint8_t *bytes = (uint8_t*)&sysCfg;
for (int i = 0; i < sizeof(SYSCFG); i++) bytes[i] = f.read();
f.close();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded configuration from spiffs count %d"), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("Config: ERROR - Loading configuration failed"));
}
} else {
#endif // USE_SPIFFS
struct SYSCFGH {
unsigned long cfg_holder;
unsigned long saveFlag;
} _sysCfgH;
noInterrupts();
spi_flash_read((CFG_LOCATION) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
spi_flash_read((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
if (sysCfg.saveFlag < _sysCfgH.saveFlag)
spi_flash_read((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
interrupts();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded configuration from flash at %X and count %d"), CFG_LOCATION + (sysCfg.saveFlag &1), sysCfg.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
}
}
// snprintf_P(log, sizeof(log), PSTR("Config: Check 1 for migration (%08X)"), sysCfg.version);
// addLog(LOG_LEVEL_NONE, log);
if (sysCfg.cfg_holder != CFG_HOLDER) {
if ((sysCfg.version < 0x03000000) || (sysCfg.version > 0x73000000)) {
CFG_Migrate(); // Config may be present with versions below 3.0.0
} else {
CFG_Default();
}
}
_cfgHash = getHash();
}
void CFG_Migrate()
{
char log[LOGSZ];
if (spiffsPresent()) {
if (!spiffsflag) {
#ifdef USE_SPIFFS
File f = SPIFFS.open(SPIFFS_CONFIG2, "r+");
if (f) {
uint8_t *bytes = (uint8_t*)&sysCfg2;
for (int i = 0; i < sizeof(SYSCFG2); i++) bytes[i] = f.read();
f.close();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded previous configuration from spiffs count %d"), sysCfg2.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("Config: ERROR - Loading previous configuration failed"));
}
} else {
#endif // USE_SPIFFS
struct SYSCFGH {
unsigned long cfg_holder;
unsigned long saveFlag;
} _sysCfgH;
noInterrupts();
spi_flash_read((CFG_LOCATION2) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg2, sizeof(SYSCFG2));
spi_flash_read((CFG_LOCATION2 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_sysCfgH, sizeof(SYSCFGH));
if (sysCfg2.saveFlag < _sysCfgH.saveFlag)
spi_flash_read((CFG_LOCATION2 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg2, sizeof(SYSCFG2));
interrupts();
snprintf_P(log, sizeof(log), PSTR("Config: Loaded previous configuration from flash at %X and count %d"), CFG_LOCATION2 + (sysCfg2.saveFlag &1), sysCfg2.saveFlag);
addLog(LOG_LEVEL_DEBUG, log);
}
}
// snprintf_P(log, sizeof(log), PSTR("Config: Check 2 for migration (%08X)"), sysCfg2.version);
// addLog(LOG_LEVEL_NONE, log);
if ((sysCfg2.version > 0x01000000) && (sysCfg2.version < 0x03000000)) {
CFG_Migrate_Part2(); // Config is present between version 1.0.0 and 3.0.0
} else {
CFG_Default();
}
_cfgHash = getHash();
}
void CFG_Erase()
{
char log[LOGSZ];
SpiFlashOpResult result;
uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1;
uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE;
boolean _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level);
snprintf_P(log, sizeof(log), PSTR("Config: Erasing %d flash sectors"), _sectorEnd - _sectorStart);
addLog(LOG_LEVEL_DEBUG, log);
for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) {
noInterrupts();
result = spi_flash_erase_sector(_sector);
interrupts();
if (_serialoutput) {
Serial.print(F("Flash: Erased sector "));
Serial.print(_sector);
if (result == SPI_FLASH_RESULT_OK) {
Serial.println(F(" OK"));
} else {
Serial.println(F(" Error"));
}
delay(10);
}
}
}
void CFG_Dump()
{
#define CFG_COLS 16
char log[LOGSZ];
uint16_t idx, maxrow, row, col;
uint8_t *buffer = (uint8_t *) &sysCfg;
maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS);
for (row = 0; row < maxrow; row++) {
idx = row * CFG_COLS;
snprintf_P(log, sizeof(log), PSTR("%04X:"), idx);
for (col = 0; col < CFG_COLS; col++) {
if (!(col%4)) snprintf_P(log, sizeof(log), PSTR("%s "), log);
snprintf_P(log, sizeof(log), PSTR("%s %02X"), log, buffer[idx + col]);
}
snprintf_P(log, sizeof(log), PSTR("%s |"), log);
for (col = 0; col < CFG_COLS; col++) {
// if (!(col%4)) snprintf_P(log, sizeof(log), PSTR("%s "), log);
snprintf_P(log, sizeof(log), PSTR("%s%c"), log, ((buffer[idx + col] > 0x20) && (buffer[idx + col] < 0x7F)) ? (char)buffer[idx + col] : ' ');
}
snprintf_P(log, sizeof(log), PSTR("%s|"), log);
addLog(LOG_LEVEL_INFO, log);
}
}
#ifdef USE_SPIFFS
void initSpiffs()
{
spiffsflag = 0;
if (!spiffsPresent()) {
spiffsflag = 1;
} else {
if (!SPIFFS.begin()) {
addLog_P(LOG_LEVEL_ERROR, PSTR("SPIFFS: WARNING - Failed to mount file system. Will use flash"));
spiffsflag = 2;
} else {
addLog_P(LOG_LEVEL_DEBUG, PSTR("SPIFFS: Mount successful"));
File f = SPIFFS.open(SPIFFS_CONFIG, "r");
if (!f) {
addLog_P(LOG_LEVEL_DEBUG, PSTR("SPIFFS: Formatting..."));
SPIFFS.format();
addLog_P(LOG_LEVEL_DEBUG, PSTR("SPIFFS: Formatted"));
File f = SPIFFS.open(SPIFFS_CONFIG, "w");
if (f) {
for (int i = 0; i < sizeof(SYSCFG); i++) f.write(0);
f.close();
} else {
addLog_P(LOG_LEVEL_ERROR, PSTR("SPIFFS: WARNING - Failed to init config file. Will use flash"));
spiffsflag = 3;
}
}
}
}
}
#endif // USE_SPIFFS
#include "eboot_command.h"
/*
* Based on cores/esp8266/Updater.cpp
*/
void setFlashChipMode(byte option, byte mode)
{
char log[LOGSZ];
uint8_t *_buffer;
uint32_t address;
if (option) {
eboot_command ebcmd;
eboot_command_read(&ebcmd);
address = ebcmd.args[0];
} else {
address = 0;
}
_buffer = new uint8_t[FLASH_SECTOR_SIZE];
if (spi_flash_read(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE) == SPI_FLASH_RESULT_OK) {
if (_buffer[2] != mode) {
_buffer[2] = mode &3;
noInterrupts();
if (spi_flash_erase_sector(address / FLASH_SECTOR_SIZE) == SPI_FLASH_RESULT_OK) {
spi_flash_write(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE);
}
interrupts();
snprintf_P(log, sizeof(log), PSTR("FLSH: Updated Flash Chip Mode to %d"), (option) ? mode : ESP.getFlashChipMode());
addLog(LOG_LEVEL_DEBUG, log);
}
}
delete[] _buffer;
}
/*********************************************************************************************\
* Wifi
\*********************************************************************************************/

View File

@ -1054,7 +1054,7 @@ void handleUploadDone()
}
snprintf_P(log, sizeof(log), PSTR("Upload: Error - %s"), error.c_str());
addLog(LOG_LEVEL_DEBUG, log);
sl_blank(1);
sl_blank(0);
} else {
page += F("<font color='green'>successful</font></b><br/><br/>Device will restart in a few seconds");
restartflag = 2;
@ -1099,7 +1099,7 @@ void handleUploadLoop()
return;
}
}
sl_blank(0);
sl_blank(1);
_colcount = 0;
} else if (!_uploaderror && (upload.status == UPLOAD_FILE_WRITE)) {
if (upload.totalSize == 0)

View File

@ -47,7 +47,7 @@ void ir_send_init(void)
{ "protocol": "SAMSUNG", "bits": 32, "data": 551502015 }
*/
boolean ir_send_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
{
boolean serviced = true;
boolean error = false;
@ -58,7 +58,7 @@ boolean ir_send_command(char *type, uint16_t index, char *dataBuf, uint16_t data
if (!strcmp(type,"IRSEND")) {
if (data_len) {
StaticJsonBuffer<128> jsonBuf;
JsonObject &ir_json = jsonBuf.parseObject(dataBuf);
JsonObject &ir_json = jsonBuf.parseObject(dataBufUc);
if (!ir_json.success()) {
snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Invalid JSON\"}")); // JSON decode failed
} else {

278
sonoff/xdrv_snfled.ino Normal file
View File

@ -0,0 +1,278 @@
/*
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.
*/
/*********************************************************************************************\
* Sonoff Led
\*********************************************************************************************/
uint8_t ledTable[] = {
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4,
4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8,
8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14,
14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22,
22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32,
33, 33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45,
46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78,
80, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 99,
101,102,104,105,107,108,110,111,113,114,116,117,119,121,122,124,
125,127,129,130,132,134,135,137,139,141,142,144,146,148,150,151,
153,155,157,159,161,163,165,166,168,170,172,174,176,178,180,182,
184,186,189,191,193,195,197,199,201,204,206,208,210,212,215,217,
219,221,224,226,228,231,233,235,238,240,243,245,248,250,253,255 };
uint8_t sl_dcolor[2], sl_tcolor[2], sl_lcolor[2];
uint8_t sl_power;
uint8_t sl_blankv;
uint8_t sl_any;
uint8_t sl_wakeupActive = 0;
uint8_t sl_wakeupDimmer = 0;
uint16_t sl_wakeupCntr = 0;
uint32_t Atoh(char *s)
{
uint32_t value = 0, digit;
int8_t c;
while((c = *s++)){
if('0' <= c && c <= '9')
digit = c - '0';
else if('A' <= c && c <= 'F')
digit = c - 'A' + 10;
else if('a' <= c && c<= 'f')
digit = c - 'a' + 10;
else break;
value = (value << 4) | digit;
}
return value;
}
void sl_setDim(uint8_t myDimmer)
{
float newDim, fmyCld, fmyWrm;
newDim = 100 / (float)myDimmer;
fmyCld = (float)sysCfg.led_color[0] / newDim;
fmyWrm = (float)sysCfg.led_color[1] / newDim;
sl_dcolor[0] = (uint8_t)fmyCld;
sl_dcolor[1] = (uint8_t)fmyWrm;
}
/********************************************************************************************/
void sl_init(void)
{
analogWriteRange(255); // Default is 1023 (Arduino.h)
analogWriteFreq(200); // Default is 1000 (core_esp8266_wiring_pwm.c) - Try to lower flicker
sl_blankv = 0;
sl_power = 0;
sl_any = 0;
sl_wakeupActive = 0;
}
void sl_blank(byte state)
/*
* Called by interrupt disabling routines like OTA or web upload
* state = 0: No blank
* 1: Blank led to solve flicker
*/
{
if (sysCfg.module == SONOFF_LED) {
sl_blankv = state;
sl_wakeupActive = 0;
sl_animate();
}
}
void sl_setPower(uint8_t power)
{
sl_blankv = 0;
sl_power = power &1;
sl_wakeupActive = 0;
sl_animate();
}
void sl_animate()
{
char svalue[MESSZ];
uint8_t fadeValue;
if ((sl_power == 0) || sl_blankv) { // Power Off
sl_tcolor[0] = 0;
sl_tcolor[1] = 0;
}
else {
if (!sl_wakeupActive) { // Power On
sl_setDim(sysCfg.led_dimmer[0]);
if (sysCfg.led_fade == 0) {
sl_tcolor[0] = sl_dcolor[0];
sl_tcolor[1] = sl_dcolor[1];
} else {
if ((sl_tcolor[0] != sl_dcolor[0]) || (sl_tcolor[1] != sl_dcolor[1])) {
if (sl_tcolor[0] < sl_dcolor[0]) sl_tcolor[0] += ((sl_dcolor[0] - sl_tcolor[0]) >> sysCfg.led_speed) +1;
if (sl_tcolor[1] < sl_dcolor[1]) sl_tcolor[1] += ((sl_dcolor[1] - sl_tcolor[1]) >> sysCfg.led_speed) +1;
if (sl_tcolor[0] > sl_dcolor[0]) sl_tcolor[0] -= ((sl_tcolor[0] - sl_dcolor[0]) >> sysCfg.led_speed) +1;
if (sl_tcolor[1] > sl_dcolor[1]) sl_tcolor[1] -= ((sl_tcolor[1] - sl_dcolor[1]) >> sysCfg.led_speed) +1;
}
}
} else { // Power On using wak up duration
if (sl_wakeupActive == 1) {
sl_wakeupActive = 2;
sl_tcolor[0] = 0;
sl_tcolor[1] = 0;
sl_wakeupCntr = 0;
sl_wakeupDimmer = 0;
}
sl_wakeupCntr++;
if (sl_wakeupCntr > ((sysCfg.led_wakeup * STATES) / sysCfg.led_dimmer[0])) {
sl_wakeupCntr = 0;
sl_wakeupDimmer++;
if (sl_wakeupDimmer <= sysCfg.led_dimmer[0]) {
sl_setDim(sl_wakeupDimmer);
sl_tcolor[0] = sl_dcolor[0];
sl_tcolor[1] = sl_dcolor[1];
} else {
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Wakeup\":\"Done\"}"));
mqtt_publish_topic_P(1, PSTR("WAKEUP"), svalue);
sl_wakeupActive = 0;
}
}
}
}
if ((sl_lcolor[0] != sl_tcolor[0]) || (sl_lcolor[1] != sl_tcolor[1]) || sl_any) {
sl_any = 0;
sl_lcolor[0] = sl_tcolor[0];
sl_lcolor[1] = sl_tcolor[1];
for (byte i = 0; i < 2; i++) {
if (pin[GPIO_PWM0 +i] < 99) {
analogWrite(pin[GPIO_PWM0 +i], (sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]);
}
}
}
}
/*********************************************************************************************\
* Commands
\*********************************************************************************************/
boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
{
boolean serviced = true;
if (!strcmp(type,"COLOR")) {
uint8_t my_color[5];
if (data_len == 4) {
char ccold[3], cwarm[3];
memcpy(ccold, dataBufUc, 2);
ccold[2] = '\0';
memcpy(cwarm, dataBufUc + 2, 2);
cwarm[2] = '\0';
my_color[0] = Atoh(ccold);
my_color[1] = Atoh(cwarm);
uint16_t temp = my_color[0];
if (temp < my_color[1]) temp = my_color[1];
float mDim = (float)temp / 2.55;
sysCfg.led_dimmer[0] = (uint8_t)mDim;
float newDim = 100 / mDim;
float fmyCold = (float)my_color[0] * newDim;
float fmyWarm = (float)my_color[1] * newDim;
sysCfg.led_color[0] = (uint8_t)fmyCold;
sysCfg.led_color[1] = (uint8_t)fmyWarm;
do_cmnd_power(index, 1);
#ifdef USE_DOMOTICZ
mqtt_publishDomoticzPowerState(index);
#endif // USE_DOMOTICZ
}
sl_setDim(sysCfg.led_dimmer[0]);
uint16_t color = (uint16_t)sl_dcolor[0] << 8;
color += (uint16_t)sl_dcolor[1];
snprintf_P(svalue, ssvalue, PSTR("{\"Color\":\"%04X\"}"), color);
}
else if (!strcmp(type,"DIMMER")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 100)) {
sysCfg.led_dimmer[0] = payload;
do_cmnd_power(index, 1);
#ifdef USE_DOMOTICZ
mqtt_publishDomoticzPowerState(index);
#endif // USE_DOMOTICZ
}
snprintf_P(svalue, ssvalue, PSTR("{\"Dimmer\":%d}"), sysCfg.led_dimmer[0]);
}
else if (!strcmp(type,"LEDTABLE")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
switch (payload) {
case 0: // Off
case 1: // On
sysCfg.led_table = payload;
break;
case 2: // Toggle
sysCfg.led_table ^= 1;
break;
}
sl_any = 1;
}
snprintf_P(svalue, ssvalue, PSTR("{\"LedTable\":\"%s\"}"), (sysCfg.led_table) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"FADE")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
switch (payload) {
case 0: // Off
case 1: // On
sysCfg.led_fade = payload;
break;
case 2: // Toggle
sysCfg.led_fade ^= 1;
break;
}
}
snprintf_P(svalue, ssvalue, PSTR("{\"Fade\":\"%s\"}"), (sysCfg.led_fade) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"SPEED")) { // 1 - fast, 8 - slow
if ((data_len > 0) && (payload > 0) && (payload <= 8)) {
sysCfg.led_speed = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"Speed\":%d}"), sysCfg.led_speed);
}
else if (!strcmp(type,"WAKEUPDURATION")) {
if ((data_len > 0) && (payload > 0) && (payload < 3601)) {
sysCfg.led_wakeup = payload;
sl_wakeupActive = 0;
}
snprintf_P(svalue, ssvalue, PSTR("{\"WakeUpDuration\":%d}"), sysCfg.led_wakeup);
}
else if (!strcmp(type,"WAKEUP")) {
do_cmnd_power(index, 1);
sl_wakeupActive = 1;
snprintf_P(svalue, ssvalue, PSTR("{\"Wakeup\":\"Started\"}"));
}
else {
serviced = false; // Unknown command
}
return serviced;
}

View File

@ -90,7 +90,7 @@ uint8_t speedValues[6] = {
10, // Slow
6, // Fast
2 }; // Fastest
/*
uint8_t ledTable[] = {
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -108,7 +108,7 @@ uint8_t ledTable[] = {
153,155,157,159,161,163,165,166,168,170,172,174,176,178,180,182,
184,186,189,191,193,195,197,199,201,204,206,208,210,212,215,217,
219,221,224,226,228,231,233,235,238,240,243,245,248,250,253,255 };
*/
uint8_t lany = 0;
RgbColor dcolor, tcolor, lcolor;