3.9.5 2017018
* Fix error message in case of wrong Domoticz command
This commit is contained in:
arendst 2017-01-28 16:31:11 +01:00
parent ae935d4676
commit eaf9e3d6cf
7 changed files with 296 additions and 253 deletions

View File

@ -1,12 +1,11 @@
## 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.4** - See ```_releasenotes.ino``` for change information.
Current version is **3.9.5** - 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```.
- After reboot select config menu again or use commands ```GPIOs``` and ```GPIO``` to change GPIO with desired sensor.
- Some features still need to be ironed out.
<img alt="Sonoff" src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoffbasic.jpg" width="250" align="right" />
See [Wiki](wiki) for more information.<br />

Binary file not shown.

View File

@ -1,4 +1,7 @@
/* 3.9.4 20170127
/* 3.9.5 2017018
* Fix error message in case of wrong Domoticz command
*
* 3.9.4 20170127
* Fix Sonoff Dual Relay switching (#287)
*
* 3.9.3 20170127

View File

@ -10,7 +10,7 @@
* ====================================================
*/
#define VERSION 0x03090400 // 3.9.4
#define VERSION 0x03090500 // 3.9.5
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
enum week_t {Last, First, Second, Third, Fourth};
@ -31,12 +31,6 @@ enum led_t {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, L
//#define USE_SPIFFS // Switch persistent configuration from flash to spiffs (+24k code, +0.6k mem)
/*********************************************************************************************\
* Not released yet
\*********************************************************************************************/
#define FEATURE_POWER_LIMIT
/*********************************************************************************************\
* No user configurable items below
\*********************************************************************************************/
@ -410,20 +404,6 @@ uint8_t i2c_flg = 0; // I2C configured
boolean mDNSbegun = false;
byte hlw_pminflg = 0;
byte hlw_pmaxflg = 0;
byte hlw_uminflg = 0;
byte hlw_umaxflg = 0;
byte hlw_iminflg = 0;
byte hlw_imaxflg = 0;
byte power_steady_cntr;
#ifdef FEATURE_POWER_LIMIT
byte hlw_mkwh_state = 0;
byte hlw_mplr_counter = 0;
uint16_t hlw_mplh_counter = 0;
uint16_t hlw_mplw_counter = 0;
#endif // FEATURE_POWER_LIMIT
/********************************************************************************************/
void CFG_DefaultSet()
@ -776,7 +756,7 @@ void setRelay(uint8_t power)
}
}
}
power_steady_cntr = 2;
hlw_setPowerSteadyCounter(2);
}
void setLed(uint8_t state)
@ -1578,11 +1558,6 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
}
#ifdef USE_DOMOTICZ
else if (sysCfg.mqtt_enabled && !strncmp(type,"DOMOTICZ...",8)) {
domoticz_commands(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue));
}
#endif // USE_DOMOTICZ
else if (sysCfg.mqtt_enabled && !strcmp(type,"GROUPTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_grptopic))) {
for(i = 0; i <= data_len; i++)
@ -1661,209 +1636,19 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
snprintf_P(stemp1, sizeof(stemp1), PSTR("%s"), (!strcmp(sysCfg.mqtt_subtopic,"POWER")) ? "Power" : "Light");
snprintf_P(svalue, sizeof(svalue), PSTR("{\"%sRetain\":\"%s\"}"), stemp1, (sysCfg.mqtt_power_retain) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
/*** HLW Power management Commands ***********************************************************/
else if (hlw_flg && !strcmp(type,"POWERLOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_pmin = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.value_units) ? " W" : "");
}
else if (hlw_flg && !strcmp(type,"POWERHIGH")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_pmax = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.value_units) ? " W" : "");
}
else if (hlw_flg && !strcmp(type,"VOLTAGELOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 501)) {
sysCfg.hlw_umin = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.value_units) ? " V" : "");
}
else if (hlw_flg && !strcmp(type,"VOLTAGEHIGH")) {
if ((data_len > 0) && (payload >= 0) && (payload < 501)) {
sysCfg.hlw_umax = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.value_units) ? " V" : "");
}
else if (hlw_flg && !strcmp(type,"CURRENTLOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 16001)) {
sysCfg.hlw_imin = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.value_units) ? " mA" : "");
}
else if (hlw_flg && !strcmp(type,"CURRENTHIGH")) {
if ((data_len > 0) && (payload >= 0) && (payload < 16001)) {
sysCfg.hlw_imax = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.value_units) ? " mA" : "");
}
else if (hlw_flg && !strcmp(type,"HLWPCAL")) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_pcal = (payload == 1) ? HLW_PREF_PULSE : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.value_units) ? " uS" : "");
}
else if (hlw_flg && !strcmp(type,"HLWUCAL")) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_ucal = (payload == 1) ? HLW_UREF_PULSE : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.value_units) ? " uS" : "");
}
else if (hlw_flg && !strcmp(type,"HLWICAL")) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_ical = (payload == 1) ? HLW_IREF_PULSE : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.value_units) ? " uS" : "");
}
#ifdef FEATURE_POWER_LIMIT
else if (hlw_flg && !strcmp(type,"MAXPOWER")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mpl = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.value_units) ? " W" : "");
}
else if (hlw_flg && !strcmp(type,"MAXPOWERHOLD")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mplh = (payload == 1) ? MAX_POWER_HOLD : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.value_units) ? " Sec" : "");
}
else if (hlw_flg && !strcmp(type,"MAXPOWERWINDOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mplw = (payload == 1) ? MAX_POWER_WINDOW : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.value_units) ? " Sec" : "");
}
else if (hlw_flg && !strcmp(type,"SAFEPOWER")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mspl = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.value_units) ? " W" : "");
}
else if (hlw_flg && !strcmp(type,"SAFEPOWERHOLD")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_msplh = (payload == 1) ? SAFE_POWER_HOLD : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.value_units) ? " Sec" : "");
}
else if (hlw_flg && !strcmp(type,"SAFEPOWERWINDOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 1440)) {
sysCfg.hlw_msplw = (payload == 1) ? SAFE_POWER_WINDOW : payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.value_units) ? " Min" : "");
}
else if (hlw_flg && !strcmp(type,"MAXENERGY")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mkwh = payload;
hlw_mkwh_state = 3;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.value_units) ? " Wh" : "");
}
else if (hlw_flg && !strcmp(type,"MAXENERGYSTART")) {
if ((data_len > 0) && (payload >= 0) && (payload < 24)) {
sysCfg.hlw_mkwhs = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.value_units) ? " Hr" : "");
}
#endif // FEATURE_POWER_LIMIT
/*** WS2812 Commands *************************************************************************/
#ifdef USE_WS2812
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"PIXELS")) {
if ((data_len > 0) && (payload > 0) && (payload <= WS2812_MAX_LEDS)) {
sysCfg.ws_pixels = payload;
ws2812_pixels();
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Pixels\":%d}"), sysCfg.ws_pixels);
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"LED") && (index > 0) && (index <= sysCfg.ws_pixels)) {
if (data_len == 6) {
ws2812_setColor(index, dataBufUc);
}
ws2812_getColor(index, svalue, sizeof(svalue));
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"COLOR")) {
if (data_len == 6) {
ws2812_setColor(0, dataBufUc);
power = 1;
}
ws2812_getColor(0, svalue, sizeof(svalue));
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"DIMMER")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 100)) {
sysCfg.ws_dimmer = payload;
power = 1;
#ifdef USE_DOMOTICZ
mqtt_publishDomoticzPowerState(index);
else if (sysCfg.mqtt_enabled && domoticz_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
#endif // USE_DOMOTICZ
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Dimmer\":%d}"), sysCfg.ws_dimmer);
else if (hlw_flg && hlw_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"LEDTABLE")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
switch (payload) {
case 0: // Off
case 1: // On
sysCfg.ws_ledtable = payload;
break;
case 2: // Toggle
sysCfg.ws_ledtable ^= 1;
break;
}
ws2812_update();
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedTable\":\"%s\"}"), (sysCfg.ws_ledtable) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"FADE")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
switch (payload) {
case 0: // Off
case 1: // On
sysCfg.ws_fade = payload;
break;
case 2: // Toggle
sysCfg.ws_fade ^= 1;
break;
}
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Fade\":\"%s\"}"), (sysCfg.ws_fade) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"SPEED")) { // 1 - fast, 5 - slow
if ((data_len > 0) && (payload > 0) && (payload <= 5)) {
sysCfg.ws_speed = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Speed\":%d}"), sysCfg.ws_speed);
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"WIDTH")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 4)) {
sysCfg.ws_width = payload;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Width\":%d}"), sysCfg.ws_width);
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"WAKEUP")) {
if ((data_len > 0) && (payload > 0) && (payload < 3601)) {
sysCfg.ws_wakeup = payload;
if (sysCfg.ws_scheme == 1) sysCfg.ws_scheme = 0;
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"WakeUp\":%d}"), sysCfg.ws_wakeup);
}
else if ((pin[GPIO_WS2812] < 99) && !strcmp(type,"SCHEME")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 9)) {
sysCfg.ws_scheme = payload;
if (sysCfg.ws_scheme == 1) ws2812_resetWakupState();
power = 1;
ws2812_resetStripTimer();
}
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Scheme\":%d}"), sysCfg.ws_scheme);
#ifdef USE_WS2812
else if ((pin[GPIO_WS2812] < 99) && ws2812_command(type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
// Serviced
}
#endif // USE_WS2812
/*********************************************************************************************/
else {
type = NULL;
}
@ -1895,16 +1680,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
#ifdef USE_DOMOTICZ
mqtt_publish(stopic, svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands\":\"DomoticzInTopic, DomoticzOutTopic, DomoticzIdx, DomoticzKeyIdx, DomoticzSwitchIdx, DomoticzSensorIdx, DomoticzUpdateTimer\"}"));
domoticz_commands(svalue, sizeof(svalue));
#endif // USE_DOMOTICZ
if (hlw_flg) {
mqtt_publish(stopic, svalue);
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands\":\"PowerLow, PowerHigh, VoltageLow, VoltageHigh, CurrentLow, CurrentHigh"));
#ifdef FEATURE_POWER_LIMIT
snprintf_P(svalue, sizeof(svalue), PSTR("%s, SafePower, SafePowerHold, SafePowerWindow, MaxPower, MaxPowerHold, MaxPowerWindow, MaxEnergy, MaxEnergyStart"), svalue);
#endif // FEATURE_POWER_LIMIT
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
hlw_commands(svalue, sizeof(svalue));
}
}
mqtt_publish(stopic, svalue);
@ -2116,16 +1897,6 @@ void every_second_cb()
// 1 second rtc interrupt routine
// Keep this code small (every_second is to large - it'll trip exception)
#ifdef FEATURE_POWER_LIMIT
if (rtcTime.Valid) {
if (rtc_loctime() == rtc_midnight()) {
hlw_mkwh_state = 3;
}
if ((rtcTime.Hour == sysCfg.hlw_mkwhs) && (hlw_mkwh_state == 3)) {
hlw_mkwh_state = 0;
}
}
#endif // FEATURE_POWER_LIMIT
}
void every_second()

View File

@ -182,8 +182,10 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
* Commands
\*********************************************************************************************/
void domoticz_commands(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
boolean domoticz_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
{
boolean serviced = true;
if (!strcmp(type,"DOMOTICZINTOPIC")) {
if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_in_topic))) {
strlcpy(sysCfg.domoticz_in_topic, (payload == 1) ? DOMOTICZ_IN_TOPIC : dataBuf, sizeof(sysCfg.domoticz_in_topic));
@ -229,6 +231,15 @@ void domoticz_commands(char *type, uint16_t index, char *dataBuf, uint16_t data_
}
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzUpdateTimer\":%d}"), sysCfg.domoticz_update_timer);
}
else {
serviced = false;
}
return serviced;
}
void domoticz_commands(char *svalue, uint16_t ssvalue)
{
snprintf_P(svalue, ssvalue, PSTR("{\"Commands\":\"DomoticzInTopic, DomoticzOutTopic, DomoticzIdx, DomoticzKeyIdx, DomoticzSwitchIdx, DomoticzSensorIdx, DomoticzUpdateTimer\"}"));
}
boolean domoticz_button(byte key, byte device, byte state, byte svalflg)

View File

@ -462,4 +462,107 @@ void ws2812_init()
strip->Begin();
ws2812_pixels();
}
/*********************************************************************************************\
* Commands
\*********************************************************************************************/
boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
{
boolean serviced = true;
if (!strcmp(type,"PIXELS")) {
if ((data_len > 0) && (payload > 0) && (payload <= WS2812_MAX_LEDS)) {
sysCfg.ws_pixels = payload;
ws2812_pixels();
}
snprintf_P(svalue, ssvalue, PSTR("{\"Pixels\":%d}"), sysCfg.ws_pixels);
}
else if (!strcmp(type,"LED") && (index > 0) && (index <= sysCfg.ws_pixels)) {
if (data_len == 6) {
// ws2812_setColor(index, dataBufUc);
ws2812_setColor(index, dataBuf);
}
ws2812_getColor(index, svalue, ssvalue);
}
else if (!strcmp(type,"COLOR")) {
if (data_len == 6) {
// ws2812_setColor(0, dataBufUc);
ws2812_setColor(0, dataBuf);
power = 1;
}
ws2812_getColor(0, svalue, ssvalue);
}
else if (!strcmp(type,"DIMMER")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 100)) {
sysCfg.ws_dimmer = payload;
power = 1;
#ifdef USE_DOMOTICZ
mqtt_publishDomoticzPowerState(index);
#endif // USE_DOMOTICZ
}
snprintf_P(svalue, ssvalue, PSTR("{\"Dimmer\":%d}"), sysCfg.ws_dimmer);
}
else if (!strcmp(type,"LEDTABLE")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 2)) {
switch (payload) {
case 0: // Off
case 1: // On
sysCfg.ws_ledtable = payload;
break;
case 2: // Toggle
sysCfg.ws_ledtable ^= 1;
break;
}
ws2812_update();
}
snprintf_P(svalue, ssvalue, PSTR("{\"LedTable\":\"%s\"}"), (sysCfg.ws_ledtable) ? 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.ws_fade = payload;
break;
case 2: // Toggle
sysCfg.ws_fade ^= 1;
break;
}
}
snprintf_P(svalue, ssvalue, PSTR("{\"Fade\":\"%s\"}"), (sysCfg.ws_fade) ? MQTT_STATUS_ON : MQTT_STATUS_OFF);
}
else if (!strcmp(type,"SPEED")) { // 1 - fast, 5 - slow
if ((data_len > 0) && (payload > 0) && (payload <= 5)) {
sysCfg.ws_speed = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"Speed\":%d}"), sysCfg.ws_speed);
}
else if (!strcmp(type,"WIDTH")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 4)) {
sysCfg.ws_width = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"Width\":%d}"), sysCfg.ws_width);
}
else if (!strcmp(type,"WAKEUP")) {
if ((data_len > 0) && (payload > 0) && (payload < 3601)) {
sysCfg.ws_wakeup = payload;
if (sysCfg.ws_scheme == 1) sysCfg.ws_scheme = 0;
}
snprintf_P(svalue, ssvalue, PSTR("{\"WakeUp\":%d}"), sysCfg.ws_wakeup);
}
else if (!strcmp(type,"SCHEME")) {
if ((data_len > 0) && (payload >= 0) && (payload <= 9)) {
sysCfg.ws_scheme = payload;
if (sysCfg.ws_scheme == 1) ws2812_resetWakupState();
power = 1;
ws2812_resetStripTimer();
}
snprintf_P(svalue, ssvalue, PSTR("{\"Scheme\":%d}"), sysCfg.ws_scheme);
}
else {
serviced = false;
}
return serviced;
}
#endif // USE_WS2812

View File

@ -29,10 +29,30 @@ POSSIBILITY OF SUCH DAMAGE.
* Based on Source: Shenzhen Heli Technology Co., Ltd
\*********************************************************************************************/
#define FEATURE_POWER_LIMIT false
/*********************************************************************************************/
#define HLW_PREF 10000 // 1000.0W
#define HLW_UREF 2200 // 220.0V
#define HLW_IREF 4545 // 4.545A
byte hlw_pminflg = 0;
byte hlw_pmaxflg = 0;
byte hlw_uminflg = 0;
byte hlw_umaxflg = 0;
byte hlw_iminflg = 0;
byte hlw_imaxflg = 0;
byte power_steady_cntr;
byte hlw_mkwh_state = 0;
#if FEATURE_POWER_LIMIT
byte hlw_mplr_counter = 0;
uint16_t hlw_mplh_counter = 0;
uint16_t hlw_mplw_counter = 0;
#endif // FEATURE_POWER_LIMIT
byte hlw_SELflag, hlw_cf_timer, hlw_cf1_timer, hlw_fifth_second, hlw_startup;
unsigned long hlw_cf_plen, hlw_cf_last;
unsigned long hlw_cf1_plen, hlw_cf1_last, hlw_cf1_ptot, hlw_cf1_pcnt, hlw_cf1u_plen, hlw_cf1i_plen;
@ -83,13 +103,19 @@ void hlw_200mS()
hlw_temp = (HLW_PREF * sysCfg.hlw_pcal) / hlw_len;
hlw_kWhtoday += (hlw_temp * 100) / 36;
}
if (rtc_loctime() == rtc_midnight()) {
sysCfg.hlw_kWhyesterday = hlw_kWhtoday;
hlw_kWhtoday = 0;
}
if (hlw_startup && rtcTime.Valid && (rtcTime.DayOfYear == sysCfg.hlw_kWhdoy)) {
hlw_kWhtoday = sysCfg.hlw_kWhtoday;
hlw_startup = 0;
if (rtcTime.Valid) {
if (rtc_loctime() == rtc_midnight()) {
sysCfg.hlw_kWhyesterday = hlw_kWhtoday;
hlw_kWhtoday = 0;
hlw_mkwh_state = 3;
}
if ((rtcTime.Hour == sysCfg.hlw_mkwhs) && (hlw_mkwh_state == 3)) {
hlw_mkwh_state = 0;
}
if (hlw_startup && (rtcTime.DayOfYear == sysCfg.hlw_kWhdoy)) {
hlw_kWhtoday = sysCfg.hlw_kWhtoday;
hlw_startup = 0;
}
}
}
@ -246,6 +272,11 @@ boolean hlw_margin(byte type, uint16_t margin, uint16_t value, byte &flag, byte
return (change != saveflag);
}
void hlw_setPowerSteadyCounter(byte value)
{
power_steady_cntr = 2;
}
void hlw_margin_chk()
{
char log[LOGSZ], stopic[TOPSZ], svalue[MESSZ];
@ -298,7 +329,7 @@ void hlw_margin_chk()
}
}
#ifdef FEATURE_POWER_LIMIT
#if FEATURE_POWER_LIMIT
snprintf_P(stopic, sizeof(stopic), PSTR("%s/%s/RESULT"), PUB_PREFIX, sysCfg.mqtt_topic);
// Max Power
if (sysCfg.hlw_mpl) {
@ -360,6 +391,131 @@ void hlw_margin_chk()
#endif // FEATURE_POWER_LIMIT
}
/*********************************************************************************************\
* Commands
\*********************************************************************************************/
boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
{
boolean serviced = true;
if (!strcmp(type,"POWERLOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_pmin = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.value_units) ? " W" : "");
}
else if (!strcmp(type,"POWERHIGH")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_pmax = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.value_units) ? " W" : "");
}
else if (!strcmp(type,"VOLTAGELOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 501)) {
sysCfg.hlw_umin = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.value_units) ? " V" : "");
}
else if (!strcmp(type,"VOLTAGEHIGH")) {
if ((data_len > 0) && (payload >= 0) && (payload < 501)) {
sysCfg.hlw_umax = payload;
}
snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.value_units) ? " V" : "");
}
else if (!strcmp(type,"CURRENTLOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 16001)) {
sysCfg.hlw_imin = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.value_units) ? " mA" : "");
}
else if (!strcmp(type,"CURRENTHIGH")) {
if ((data_len > 0) && (payload >= 0) && (payload < 16001)) {
sysCfg.hlw_imax = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.value_units) ? " mA" : "");
}
else if (!strcmp(type,"HLWPCAL")) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_pcal = (payload == 1) ? HLW_PREF_PULSE : payload;
}
snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.value_units) ? " uS" : "");
}
else if (!strcmp(type,"HLWUCAL")) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_ucal = (payload == 1) ? HLW_UREF_PULSE : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.value_units) ? " uS" : "");
}
else if (!strcmp(type,"HLWICAL")) {
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
sysCfg.hlw_ical = (payload == 1) ? HLW_IREF_PULSE : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.value_units) ? " uS" : "");
}
#if FEATURE_POWER_LIMIT
else if (!strcmp(type,"MAXPOWER")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mpl = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.value_units) ? " W" : "");
}
else if (!strcmp(type,"MAXPOWERHOLD")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mplh = (payload == 1) ? MAX_POWER_HOLD : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.value_units) ? " Sec" : "");
}
else if (!strcmp(type,"MAXPOWERWINDOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mplw = (payload == 1) ? MAX_POWER_WINDOW : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.value_units) ? " Sec" : "");
}
else if (!strcmp(type,"SAFEPOWER")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mspl = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.value_units) ? " W" : "");
}
else if (!strcmp(type,"SAFEPOWERHOLD")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_msplh = (payload == 1) ? SAFE_POWER_HOLD : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.value_units) ? " Sec" : "");
}
else if (!strcmp(type,"SAFEPOWERWINDOW")) {
if ((data_len > 0) && (payload >= 0) && (payload < 1440)) {
sysCfg.hlw_msplw = (payload == 1) ? SAFE_POWER_WINDOW : payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.value_units) ? " Min" : "");
}
else if (!strcmp(type,"MAXENERGY")) {
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
sysCfg.hlw_mkwh = payload;
hlw_mkwh_state = 3;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.value_units) ? " Wh" : "");
}
else if (!strcmp(type,"MAXENERGYSTART")) {
if ((data_len > 0) && (payload >= 0) && (payload < 24)) {
sysCfg.hlw_mkwhs = payload;
}
snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.value_units) ? " Hr" : "");
}
#endif // FEATURE_POWER_LIMIT
else {
serviced = false;
}
return serviced;
}
void hlw_commands(char *svalue, uint16_t ssvalue)
{
snprintf_P(svalue, ssvalue, PSTR("{\"Commands\":\"PowerLow, PowerHigh, VoltageLow, VoltageHigh, CurrentLow, CurrentHigh%s\"}"),
(FEATURE_POWER_LIMIT)?"SafePower, SafePowerHold, SafePowerWindow, MaxPower, MaxPowerHold, MaxPowerWindow, MaxEnergy, MaxEnergyStart":"");
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/