mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
CleanUp, GROUP fixes&optimization, binaries
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,23 +1,19 @@
|
|||||||
#include "bright.h"
|
#include "bright.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
uint8_t getBright(uint8_t percent)
|
uint8_t getBright255(uint8_t percent255)
|
||||||
{
|
|
||||||
int index = map(percent,0,100,0,255);
|
|
||||||
if (index>255) index=255;
|
|
||||||
return getBright255(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t getBright255(uint8_t percent)
|
|
||||||
{
|
{
|
||||||
#ifdef BRIGHT_LINEAR
|
#ifdef BRIGHT_LINEAR
|
||||||
return percent;
|
return percent255;
|
||||||
#else
|
#else
|
||||||
|
return pgm_read_byte_near(stepvar[percent255]);
|
||||||
|
/*
|
||||||
int val = stepvar[index];
|
int val = stepvar[index];
|
||||||
if (val>255) val=255;
|
if (val>255) val=255;
|
||||||
Serial.print(F("Bright:"));
|
Serial.print(F("Bright:"));
|
||||||
Serial.print(percent);
|
Serial.print(percent);
|
||||||
Serial.print(F("->"));
|
Serial.print(F("->"));
|
||||||
Serial.println(val);
|
Serial.println(val);
|
||||||
return val;
|
return val;*/
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifdef BRIGHT_LOG
|
#ifdef BRIGHT_LOG
|
||||||
|
#undef BRIGHT_LINEAR
|
||||||
const uint8_t stepvar[] PROGMEM =
|
const uint8_t stepvar[] PROGMEM =
|
||||||
{
|
{
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -55,6 +56,7 @@ const uint8_t stepvar[] PROGMEM =
|
|||||||
|
|
||||||
|
|
||||||
#ifdef BRIGHT_STEP
|
#ifdef BRIGHT_STEP
|
||||||
|
#undef BRIGHT_LINEAR
|
||||||
const uint8_t stepvar[] PROGMEM =
|
const uint8_t stepvar[] PROGMEM =
|
||||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
@@ -101,5 +103,4 @@ const uint8_t stepvar[] PROGMEM =
|
|||||||
0xF6, 0xF9, 0xFC, 0xFF};
|
0xF6, 0xF9, 0xFC, 0xFF};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t getBright(uint8_t percent);
|
uint8_t getBright255(uint8_t percent255);
|
||||||
uint8_t getBright255(uint8_t percent);
|
|
||||||
|
|||||||
@@ -573,38 +573,40 @@ return 0;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recursive function with small stack consumption
|
// Recursive function with small stack consumption
|
||||||
int digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem)
|
// if cmd defined - execute Ctrl for any group members recursively
|
||||||
{ if (!itemArr || itemArr->type!=aJson_Array) return 0;
|
// else performs Activity check for group members and return true if any member is active
|
||||||
debugSerial<< F("Sub:")<<subItem<<endl;
|
bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem)
|
||||||
|
{ if (!itemArr || itemArr->type!=aJson_Array) return false;
|
||||||
// Iterate across array of names
|
// Iterate across array of names
|
||||||
aJsonObject *i = itemArr->child;
|
aJsonObject *i = itemArr->child;
|
||||||
configLocked++;
|
configLocked++;
|
||||||
while (i) {
|
while (i) {
|
||||||
if (i->type == aJson_String)
|
if (i->type == aJson_String)
|
||||||
{ debugSerial<< i->valuestring<<endl;
|
{ //debugSerial<< i->valuestring<<endl;
|
||||||
aJsonObject *nextItem = aJson.getObjectItem(items, i->valuestring);
|
aJsonObject *nextItem = aJson.getObjectItem(items, i->valuestring);
|
||||||
if (nextItem && nextItem->type == aJson_Array)
|
if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item
|
||||||
{
|
|
||||||
short itemtype = aJson.getArrayItem(nextItem,0)->valueint;
|
|
||||||
if (itemtype == CH_GROUP)
|
|
||||||
{
|
|
||||||
aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1);
|
|
||||||
digGroup(itemSubArray,cmd,subItem);
|
|
||||||
}
|
|
||||||
else // Normal channel
|
|
||||||
{
|
{
|
||||||
Item it(nextItem);
|
Item it(nextItem);
|
||||||
if (it.isValid()) it.Ctrl(*cmd,subItem);
|
if (cmd && it.isValid()) it.Ctrl(*cmd,subItem,false); //Execute (non recursive)
|
||||||
|
//Retrieve itemType
|
||||||
|
aJsonObject * itemtype = aJson.getArrayItem(nextItem,0);
|
||||||
|
if (itemtype && itemtype->type == aJson_Int && itemtype->valueint == CH_GROUP)
|
||||||
|
{ //is Group
|
||||||
|
aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1);
|
||||||
|
short res = digGroup(itemSubArray,cmd,subItem);
|
||||||
|
if (!cmd && res) return true; //Not execution, just activity check. If any channel is active - return true
|
||||||
}
|
}
|
||||||
|
else // Normal channel
|
||||||
|
if (!cmd && it.isValid() && it.isActive()) return true; //Not execution, just activity check. If any channel is active - return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i = i->next;
|
i = i->next;
|
||||||
} //while
|
} //while
|
||||||
configLocked--;
|
configLocked--;
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Item::Ctrl(itemCmd cmd, char* subItem)
|
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||||
{
|
{
|
||||||
//char stringBuffer[16];
|
//char stringBuffer[16];
|
||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
@@ -636,7 +638,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
|
|
||||||
|
|
||||||
bool chActive = (isActive()>0);
|
bool chActive = (isActive()>0);
|
||||||
bool toExecute = (chActive>0); // execute if channel is active now
|
bool toExecute = chActive; // execute if channel is active now
|
||||||
bool scale100 = false;
|
bool scale100 = false;
|
||||||
debugSerial<<endl;
|
debugSerial<<endl;
|
||||||
|
|
||||||
@@ -653,11 +655,6 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else
|
|
||||||
// Group channel
|
|
||||||
// if (! operation) return -1;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
itemCmd st(ST_VOID,CMD_VOID);
|
itemCmd st(ST_VOID,CMD_VOID);
|
||||||
|
|
||||||
@@ -714,7 +711,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
case CMD_DN:
|
case CMD_DN:
|
||||||
case CMD_UP:
|
case CMD_UP:
|
||||||
{
|
{
|
||||||
//if (itemType == CH_GROUP) break; ////bug here
|
|
||||||
st.Cmd(CMD_VOID); // Converting to SET value command
|
st.Cmd(CMD_VOID); // Converting to SET value command
|
||||||
short step=0;
|
short step=0;
|
||||||
if (cmd.isValue()) step=cmd.getInt();
|
if (cmd.isValue()) step=cmd.getInt();
|
||||||
@@ -726,7 +723,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
case S_NOTFOUND:
|
case S_NOTFOUND:
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
case S_SET:
|
case S_SET:
|
||||||
// case S_ESET:
|
|
||||||
if (st.incrementPercents(step))
|
if (st.incrementPercents(step))
|
||||||
{
|
{
|
||||||
st.saveItem(this);
|
st.saveItem(this);
|
||||||
@@ -735,7 +732,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case S_HUE:
|
case S_HUE:
|
||||||
if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
|
//if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
|
||||||
if (st.incrementH(step))
|
if (st.incrementH(step))
|
||||||
{
|
{
|
||||||
st.setSuffix(S_SET);
|
st.setSuffix(S_SET);
|
||||||
@@ -744,7 +741,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_SAT:
|
case S_SAT:
|
||||||
if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
|
//if (cmd.isColor()) st.convertTo(ST_HSV255);//Extend storage for color channel
|
||||||
if (st.incrementS(step))
|
if (st.incrementS(step))
|
||||||
{
|
{
|
||||||
st.setSuffix(S_SET);
|
st.setSuffix(S_SET);
|
||||||
@@ -757,9 +754,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
} //Case UP/DOWN
|
} //Case UP/DOWN
|
||||||
break;
|
break;
|
||||||
case CMD_VOID: // No commands, just set value
|
case CMD_VOID: // No commands, just set value
|
||||||
////if (itemType == CH_GROUP ) break; ////
|
|
||||||
if (!cmd.isValue()) break;
|
if (!cmd.isValue()) break;
|
||||||
//// if ( cType == CH_RGB || cType == CH_RGBW || cType == CH_GROUP )
|
|
||||||
switch (suffixCode)
|
switch (suffixCode)
|
||||||
{
|
{
|
||||||
case S_NOTFOUND: //For empty (universal) OPENHAB suffix - turn ON/OFF automatically
|
case S_NOTFOUND: //For empty (universal) OPENHAB suffix - turn ON/OFF automatically
|
||||||
@@ -824,15 +820,13 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
|
|||||||
toExecute=true;
|
toExecute=true;
|
||||||
} //Switch commands
|
} //Switch commands
|
||||||
|
|
||||||
//==================
|
|
||||||
|
|
||||||
if (driver) //New style modular code
|
if (driver) //New style modular code
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
switch (cmd.getCmd())
|
switch (cmd.getCmd())
|
||||||
{
|
{
|
||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
if (!chActive>0) //if channel was'nt active before CMD_XON
|
if (!chActive) //if channel was'nt active before CMD_XON
|
||||||
{
|
{
|
||||||
debugSerial<<F("Turning XON\n");
|
debugSerial<<F("Turning XON\n");
|
||||||
res = driver->Ctrl(st.Cmd(CMD_ON), subItem);
|
res = driver->Ctrl(st.Cmd(CMD_ON), subItem);
|
||||||
@@ -846,7 +840,7 @@ if (driver) //New style modular code
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
if (chActive>0) //if channel was active before CMD_HALT
|
if (chActive) //if channel was active before CMD_HALT
|
||||||
{
|
{
|
||||||
res = driver->Ctrl(st.Cmd(CMD_OFF), subItem);
|
res = driver->Ctrl(st.Cmd(CMD_OFF), subItem);
|
||||||
setCmd(CMD_HALT);
|
setCmd(CMD_HALT);
|
||||||
@@ -899,29 +893,15 @@ else //Driver not found
|
|||||||
{
|
{
|
||||||
switch (itemType) {
|
switch (itemType) {
|
||||||
case CH_GROUP:
|
case CH_GROUP:
|
||||||
{
|
|
||||||
if (itemArg->type == aJson_Array && operation) {
|
if (allowRecursion && itemArg->type == aJson_Array && operation)
|
||||||
digGroup(itemArg,&cmd,subItem);
|
digGroup(itemArg,&cmd,subItem);
|
||||||
/*
|
|
||||||
aJsonObject *i = itemArg->child;
|
|
||||||
configLocked++;
|
|
||||||
while (i) {
|
|
||||||
if (i->type == aJson_String)
|
|
||||||
{
|
|
||||||
Item it(i->valuestring);
|
|
||||||
it.Ctrl(cmd,subItem);
|
|
||||||
}
|
|
||||||
i = i->next;
|
|
||||||
} //while
|
|
||||||
configLocked--;
|
|
||||||
*/
|
|
||||||
} //if
|
|
||||||
} //case
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// rest of Legacy monolite core code (to be refactored )
|
/// rest of Legacy monolite core code (to be refactored ) BEGIN ///
|
||||||
case CH_RELAY:
|
case CH_RELAY:
|
||||||
{
|
{
|
||||||
short iaddr=getArg();
|
short iaddr=getArg();
|
||||||
@@ -966,7 +946,6 @@ switch (itemType) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case S_SET:
|
case S_SET:
|
||||||
// case S_ESET:
|
|
||||||
st.saveItem(this);
|
st.saveItem(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -983,8 +962,9 @@ switch (itemType) {
|
|||||||
case CH_VCTEMP:
|
case CH_VCTEMP:
|
||||||
if (toExecute) VacomSetHeat(st);
|
if (toExecute) VacomSetHeat(st);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
/// rest of Legacy monolite core code (to be refactored ) END ///
|
||||||
|
|
||||||
} //switch
|
} //switch
|
||||||
if (st.isCommand())
|
if (st.isCommand())
|
||||||
{
|
{
|
||||||
@@ -1006,9 +986,6 @@ switch (itemType) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void printActiveStatus(bool active)
|
void printActiveStatus(bool active)
|
||||||
{
|
{
|
||||||
if (active) debugSerial<<F(" active ");
|
if (active) debugSerial<<F(" active ");
|
||||||
@@ -1059,36 +1036,16 @@ int Item::isActive() {
|
|||||||
case CH_GROUP: //make recursive calculation - is it some active in group
|
case CH_GROUP: //make recursive calculation - is it some active in group
|
||||||
if (itemArg->type == aJson_Array) {
|
if (itemArg->type == aJson_Array) {
|
||||||
debugSerial<<F(" Grp:");
|
debugSerial<<F(" Grp:");
|
||||||
aJsonObject *i = itemArg->child;
|
val=digGroup(itemArg);
|
||||||
while (i) {
|
printActiveStatus(val);
|
||||||
if (i->type == aJson_String)
|
return val;
|
||||||
{
|
|
||||||
Item it(i->valuestring);
|
|
||||||
|
|
||||||
if (it.isValid() && it.isActive()>0) {
|
|
||||||
printActiveStatus(true);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = i->next;
|
|
||||||
} //while
|
|
||||||
printActiveStatus(false);
|
|
||||||
return 0;
|
|
||||||
} //if
|
} //if
|
||||||
break;
|
break;
|
||||||
|
case CH_MODBUS: //Legacy channels
|
||||||
|
|
||||||
//case CH_RGBW:
|
|
||||||
//case CH_RGB:
|
|
||||||
//case CH_DIMMER: //Legacy channels
|
|
||||||
case CH_MODBUS:
|
|
||||||
case CH_VC:
|
case CH_VC:
|
||||||
|
|
||||||
|
|
||||||
val = st.getPercents255(); //Light volume
|
val = st.getPercents255(); //Light volume
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case CH_VCTEMP:
|
case CH_VCTEMP:
|
||||||
case CH_PWM:
|
case CH_PWM:
|
||||||
val = st.getInt();
|
val = st.getInt();
|
||||||
@@ -1103,6 +1060,237 @@ int Item::isActive() {
|
|||||||
if (val) return 1; else return 0;
|
if (val) return 1; else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Item::Poll(int cause) {
|
||||||
|
|
||||||
|
switch (cause)
|
||||||
|
{
|
||||||
|
case POLLING_SLOW:
|
||||||
|
// Legacy polling
|
||||||
|
switch (itemType) {
|
||||||
|
#ifndef MODBUS_DISABLE
|
||||||
|
case CH_MODBUS:
|
||||||
|
checkModbusDimmer();
|
||||||
|
sendDelayedStatus();
|
||||||
|
return INTERVAL_SLOW_POLLING;
|
||||||
|
break;
|
||||||
|
case CH_VC:
|
||||||
|
checkFM();
|
||||||
|
sendDelayedStatus();
|
||||||
|
return INTERVAL_SLOW_POLLING;
|
||||||
|
break;
|
||||||
|
case CH_VCTEMP:
|
||||||
|
checkHeatRetry();
|
||||||
|
sendDelayedStatus();
|
||||||
|
return INTERVAL_SLOW_POLLING;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
/* case CH_RGB: //All channels with slider generate too many updates
|
||||||
|
case CH_RGBW:
|
||||||
|
case CH_DIMMER:
|
||||||
|
case CH_PWM:
|
||||||
|
case CH_VCTEMP:
|
||||||
|
case CH_THERMO:
|
||||||
|
case CH_GROUP:*/
|
||||||
|
default:
|
||||||
|
sendDelayedStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (driver && driver->Status())
|
||||||
|
{
|
||||||
|
return driver->Poll(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::sendDelayedStatus()
|
||||||
|
{ long int flags = getFlag(SEND_COMMAND | SEND_PARAMETERS);
|
||||||
|
|
||||||
|
if (flags && lanStatus==OPERATION)
|
||||||
|
{
|
||||||
|
SendStatus(flags);//(SEND_COMMAND | SEND_PARAMETERS);
|
||||||
|
clearFlag(SEND_COMMAND | SEND_PARAMETERS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Item::SendStatus(int sendFlags) {
|
||||||
|
|
||||||
|
if ((sendFlags & SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
|
||||||
|
setFlag(sendFlags & (SEND_COMMAND | SEND_PARAMETERS));
|
||||||
|
debugSerial<<F("Status deffered\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else return SendStatusImmediate(sendFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Item::SendStatusImmediate(int sendFlags) {
|
||||||
|
{
|
||||||
|
itemCmd st(ST_VOID,CMD_VOID);
|
||||||
|
st.loadItem(this, true);
|
||||||
|
|
||||||
|
sendFlags |= getFlag(SEND_COMMAND | SEND_PARAMETERS); //if some delayed status is pending
|
||||||
|
|
||||||
|
char addrstr[48];
|
||||||
|
char valstr[20] = "";
|
||||||
|
char cmdstr[8] = "";
|
||||||
|
|
||||||
|
if (sendFlags & SEND_COMMAND)
|
||||||
|
{
|
||||||
|
// Preparing Command payload //////////////
|
||||||
|
switch (st.getCmd()) {
|
||||||
|
case CMD_ON:
|
||||||
|
case CMD_XON:
|
||||||
|
case CMD_AUTO:
|
||||||
|
case CMD_HEAT:
|
||||||
|
case CMD_COOL:
|
||||||
|
strcpy_P(cmdstr, ON_P);
|
||||||
|
break;
|
||||||
|
case CMD_OFF:
|
||||||
|
case CMD_HALT:
|
||||||
|
strcpy_P(cmdstr, OFF_P);
|
||||||
|
break;
|
||||||
|
case CMD_VOID:
|
||||||
|
case CMD_RGB:
|
||||||
|
sendFlags &= ~SEND_COMMAND; // Not send command for parametrized req
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
debugSerial<<F("Unknown cmd \n");
|
||||||
|
sendFlags &= ~SEND_COMMAND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// publish to MQTT - OpenHab Legacy style to
|
||||||
|
// myhome/s_out/item - mix: value and command
|
||||||
|
// send only for OH bus supported types
|
||||||
|
|
||||||
|
switch (st.getArgType())
|
||||||
|
{
|
||||||
|
case ST_PERCENTS255:
|
||||||
|
case ST_HSV255:
|
||||||
|
case ST_FLOAT_CELSIUS:
|
||||||
|
|
||||||
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
|
{
|
||||||
|
|
||||||
|
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
||||||
|
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||||
|
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,true);
|
||||||
|
|
||||||
|
if (sendFlags & SEND_PARAMETERS && st.getCmd() != CMD_OFF && st.getCmd() != CMD_HALT)
|
||||||
|
{
|
||||||
|
mqttClient.publish(addrstr, valstr, true);
|
||||||
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
||||||
|
}
|
||||||
|
else if (sendFlags & SEND_COMMAND)
|
||||||
|
{
|
||||||
|
mqttClient.publish(addrstr, cmdstr, true);
|
||||||
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFlag(sendFlags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// publush to MQTT - New style to
|
||||||
|
// myhome/s_out/item/cmd
|
||||||
|
// myhome/s_out/item/set
|
||||||
|
|
||||||
|
if (sendFlags & SEND_PARAMETERS)
|
||||||
|
{
|
||||||
|
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
||||||
|
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||||
|
strncat(addrstr, "/", sizeof(addrstr));
|
||||||
|
|
||||||
|
// Preparing parameters payload //////////
|
||||||
|
switch (st.getArgType()) {
|
||||||
|
case ST_RGB:
|
||||||
|
case ST_RGBW:
|
||||||
|
//valstr[0]='#';
|
||||||
|
st.Cmd(CMD_RGB);
|
||||||
|
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS|SEND_COMMAND);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,(SCALE_VOLUME_100));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (st.getArgType()) {
|
||||||
|
case ST_RGB:
|
||||||
|
case ST_RGBW:
|
||||||
|
strncat_P(addrstr, SET_P, sizeof(addrstr));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strncat_P(addrstr, SET_P, sizeof(addrstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
||||||
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
|
{
|
||||||
|
mqttClient.publish(addrstr, valstr,true);
|
||||||
|
clearFlag(SEND_PARAMETERS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFlag(sendFlags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sendFlags & SEND_COMMAND)
|
||||||
|
{
|
||||||
|
// Some additional preparing for extended set of commands:
|
||||||
|
switch (st.getCmd()) {
|
||||||
|
case CMD_AUTO:
|
||||||
|
strcpy_P(cmdstr, AUTO_P);
|
||||||
|
break;
|
||||||
|
case CMD_HEAT:
|
||||||
|
strcpy_P(cmdstr, HEAT_P);
|
||||||
|
break;
|
||||||
|
case CMD_COOL:
|
||||||
|
strcpy_P(cmdstr, COOL_P);
|
||||||
|
break;
|
||||||
|
case CMD_ON:
|
||||||
|
case CMD_XON:
|
||||||
|
if (itemType == CH_THERMO) strcpy_P(cmdstr, AUTO_P);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
||||||
|
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||||
|
strncat(addrstr, "/", sizeof(addrstr));
|
||||||
|
strncat_P(addrstr, CMD_P, sizeof(addrstr));
|
||||||
|
|
||||||
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
||||||
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
|
{
|
||||||
|
mqttClient.publish(addrstr, cmdstr,true);
|
||||||
|
clearFlag(SEND_COMMAND);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFlag(sendFlags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Item::getChanType()
|
||||||
|
{
|
||||||
|
if (driver) return driver->getChanType();
|
||||||
|
return itemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////// Begin of legacy MODBUS code - to be moved in separate module /////////////////////
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
addr 10d
|
addr 10d
|
||||||
Снять аварию 42001 (2001=7d1) =>4
|
Снять аварию 42001 (2001=7d1) =>4
|
||||||
@@ -1572,233 +1760,3 @@ int Item::checkModbusDimmer(int data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int Item::Poll(int cause) {
|
|
||||||
|
|
||||||
switch (cause)
|
|
||||||
{
|
|
||||||
case POLLING_SLOW:
|
|
||||||
// Legacy polling
|
|
||||||
switch (itemType) {
|
|
||||||
#ifndef MODBUS_DISABLE
|
|
||||||
case CH_MODBUS:
|
|
||||||
checkModbusDimmer();
|
|
||||||
sendDelayedStatus();
|
|
||||||
return INTERVAL_SLOW_POLLING;
|
|
||||||
break;
|
|
||||||
case CH_VC:
|
|
||||||
checkFM();
|
|
||||||
sendDelayedStatus();
|
|
||||||
return INTERVAL_SLOW_POLLING;
|
|
||||||
break;
|
|
||||||
case CH_VCTEMP:
|
|
||||||
checkHeatRetry();
|
|
||||||
sendDelayedStatus();
|
|
||||||
return INTERVAL_SLOW_POLLING;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
/* case CH_RGB: //All channels with slider generate too many updates
|
|
||||||
case CH_RGBW:
|
|
||||||
case CH_DIMMER:
|
|
||||||
case CH_PWM:
|
|
||||||
case CH_VCTEMP:
|
|
||||||
case CH_THERMO:
|
|
||||||
case CH_GROUP:*/
|
|
||||||
default:
|
|
||||||
sendDelayedStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (driver && driver->Status())
|
|
||||||
{
|
|
||||||
return driver->Poll(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Item::sendDelayedStatus()
|
|
||||||
{ long int flags = getFlag(SEND_COMMAND | SEND_PARAMETERS);
|
|
||||||
|
|
||||||
if (flags && lanStatus==OPERATION)
|
|
||||||
{
|
|
||||||
SendStatus(flags);//(SEND_COMMAND | SEND_PARAMETERS);
|
|
||||||
clearFlag(SEND_COMMAND | SEND_PARAMETERS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Item::SendStatus(int sendFlags) {
|
|
||||||
|
|
||||||
if ((sendFlags & SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
|
|
||||||
setFlag(sendFlags & (SEND_COMMAND | SEND_PARAMETERS));
|
|
||||||
debugSerial<<F("Status deffered\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else return SendStatusImmediate(sendFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Item::SendStatusImmediate(int sendFlags) {
|
|
||||||
{
|
|
||||||
itemCmd st(ST_VOID,CMD_VOID);
|
|
||||||
st.loadItem(this, true);
|
|
||||||
|
|
||||||
sendFlags |= getFlag(SEND_COMMAND | SEND_PARAMETERS); //if some delayed status is pending
|
|
||||||
|
|
||||||
char addrstr[48];
|
|
||||||
char valstr[20] = "";
|
|
||||||
char cmdstr[8] = "";
|
|
||||||
|
|
||||||
if (sendFlags & SEND_COMMAND)
|
|
||||||
{
|
|
||||||
// Preparing Command payload //////////////
|
|
||||||
switch (st.getCmd()) {
|
|
||||||
case CMD_ON:
|
|
||||||
case CMD_XON:
|
|
||||||
case CMD_AUTO:
|
|
||||||
case CMD_HEAT:
|
|
||||||
case CMD_COOL:
|
|
||||||
strcpy_P(cmdstr, ON_P);
|
|
||||||
break;
|
|
||||||
case CMD_OFF:
|
|
||||||
case CMD_HALT:
|
|
||||||
strcpy_P(cmdstr, OFF_P);
|
|
||||||
break;
|
|
||||||
case CMD_VOID:
|
|
||||||
case CMD_RGB:
|
|
||||||
sendFlags &= ~SEND_COMMAND; // Not send command for parametrized req
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
debugSerial<<F("Unknown cmd \n");
|
|
||||||
sendFlags &= ~SEND_COMMAND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// publish to MQTT - OpenHab Legacy style to
|
|
||||||
// myhome/s_out/item - mix: value and command
|
|
||||||
// send only for OH bus supported types
|
|
||||||
|
|
||||||
switch (st.getArgType())
|
|
||||||
{
|
|
||||||
case ST_PERCENTS255:
|
|
||||||
case ST_HSV255:
|
|
||||||
case ST_FLOAT_CELSIUS:
|
|
||||||
|
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
|
||||||
{
|
|
||||||
|
|
||||||
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
|
||||||
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
|
||||||
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,true);
|
|
||||||
|
|
||||||
if (sendFlags & SEND_PARAMETERS && st.getCmd() != CMD_OFF && st.getCmd() != CMD_HALT)
|
|
||||||
{
|
|
||||||
mqttClient.publish(addrstr, valstr, true);
|
|
||||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
|
||||||
}
|
|
||||||
else if (sendFlags & SEND_COMMAND)
|
|
||||||
{
|
|
||||||
mqttClient.publish(addrstr, cmdstr, true);
|
|
||||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setFlag(sendFlags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// publush to MQTT - New style to
|
|
||||||
// myhome/s_out/item/cmd
|
|
||||||
// myhome/s_out/item/set
|
|
||||||
|
|
||||||
if (sendFlags & SEND_PARAMETERS)
|
|
||||||
{
|
|
||||||
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
|
||||||
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
|
||||||
strncat(addrstr, "/", sizeof(addrstr));
|
|
||||||
|
|
||||||
// Preparing parameters payload //////////
|
|
||||||
switch (st.getArgType()) {
|
|
||||||
case ST_RGB:
|
|
||||||
case ST_RGBW:
|
|
||||||
//valstr[0]='#';
|
|
||||||
st.Cmd(CMD_RGB);
|
|
||||||
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS|SEND_COMMAND);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,(SCALE_VOLUME_100));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (st.getArgType()) {
|
|
||||||
case ST_RGB:
|
|
||||||
case ST_RGBW:
|
|
||||||
strncat_P(addrstr, SET_P, sizeof(addrstr));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
strncat_P(addrstr, SET_P, sizeof(addrstr));
|
|
||||||
}
|
|
||||||
|
|
||||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
|
||||||
{
|
|
||||||
mqttClient.publish(addrstr, valstr,true);
|
|
||||||
clearFlag(SEND_PARAMETERS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setFlag(sendFlags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (sendFlags & SEND_COMMAND)
|
|
||||||
{
|
|
||||||
// Some additional preparing for extended set of commands:
|
|
||||||
switch (st.getCmd()) {
|
|
||||||
case CMD_AUTO:
|
|
||||||
strcpy_P(cmdstr, AUTO_P);
|
|
||||||
break;
|
|
||||||
case CMD_HEAT:
|
|
||||||
strcpy_P(cmdstr, HEAT_P);
|
|
||||||
break;
|
|
||||||
case CMD_COOL:
|
|
||||||
strcpy_P(cmdstr, COOL_P);
|
|
||||||
break;
|
|
||||||
case CMD_ON:
|
|
||||||
case CMD_XON:
|
|
||||||
if (itemType == CH_THERMO) strcpy_P(cmdstr, AUTO_P);
|
|
||||||
}
|
|
||||||
|
|
||||||
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
|
||||||
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
|
||||||
strncat(addrstr, "/", sizeof(addrstr));
|
|
||||||
strncat_P(addrstr, CMD_P, sizeof(addrstr));
|
|
||||||
|
|
||||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
|
||||||
{
|
|
||||||
mqttClient.publish(addrstr, cmdstr,true);
|
|
||||||
clearFlag(SEND_COMMAND);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setFlag(sendFlags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Item::getChanType()
|
|
||||||
{
|
|
||||||
if (driver) return driver->getChanType();
|
|
||||||
return itemType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ extern aJsonObject *items;
|
|||||||
extern short thermoSetCurTemp(char *name, float t);
|
extern short thermoSetCurTemp(char *name, float t);
|
||||||
|
|
||||||
int txt2cmd (char * payload);
|
int txt2cmd (char * payload);
|
||||||
int digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem);
|
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL);
|
||||||
class Item
|
class Item
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -107,7 +107,7 @@ class Item
|
|||||||
boolean Setup();
|
boolean Setup();
|
||||||
void Stop();
|
void Stop();
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL);
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool allowRecursion = true);
|
||||||
int Ctrl(char * payload, char * subItem=NULL);
|
int Ctrl(char * payload, char * subItem=NULL);
|
||||||
|
|
||||||
int getArg(short n=0);
|
int getArg(short n=0);
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
#include "bright.h"
|
||||||
|
|
||||||
#ifdef ADAFRUIT_LED
|
#ifdef ADAFRUIT_LED
|
||||||
#include <Adafruit_NeoPixel.h>
|
#include <Adafruit_NeoPixel.h>
|
||||||
#else
|
#else
|
||||||
#include "FastLED.h"
|
#include "FastLED.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#include "hsv2rgb.h"
|
//#include "hsv2rgb.h"
|
||||||
|
|
||||||
int txt2cmd(char *payload) {
|
int txt2cmd(char *payload) {
|
||||||
@@ -102,6 +104,7 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
|
|||||||
case CH_PWM:
|
case CH_PWM:
|
||||||
case CH_RELAY:
|
case CH_RELAY:
|
||||||
case CH_VC:
|
case CH_VC:
|
||||||
|
case CH_MODBUS:
|
||||||
return ST_PERCENTS255;
|
return ST_PERCENTS255;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -496,17 +499,10 @@ itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
|
|||||||
|
|
||||||
case ST_HSV255:
|
case ST_HSV255:
|
||||||
{ // HSV_XX to RGB_XX translation code
|
{ // HSV_XX to RGB_XX translation code
|
||||||
int rgbSaturation;
|
int rgbSaturation=constrain(map(from.param.s, 0, 100, 0, 255),0,255);
|
||||||
int rgbValue;
|
int rgbValue = getBright255(from.param.v);
|
||||||
|
short colorT =from.param.colorTemp-1;
|
||||||
rgbSaturation =map(from.param.s, 0, 100, 0, 255);
|
|
||||||
rgbValue = from.param.v;
|
|
||||||
|
|
||||||
short colorT=from.param.colorTemp-1;
|
|
||||||
|
|
||||||
|
|
||||||
if (RGBW_flag)
|
if (RGBW_flag)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (colorT<0)
|
if (colorT<0)
|
||||||
{ //ColorTemperature not set
|
{ //ColorTemperature not set
|
||||||
@@ -884,7 +880,6 @@ itemCmd itemCmd::RGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w)
|
|||||||
|
|
||||||
itemCmd itemCmd::Cmd(uint8_t i)
|
itemCmd itemCmd::Cmd(uint8_t i)
|
||||||
{
|
{
|
||||||
// cmd.itemArgType=ST_COMMAND;
|
|
||||||
cmd.cmdCode=i;
|
cmd.cmdCode=i;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1150,7 +1150,6 @@ void printConfigSummary() {
|
|||||||
|
|
||||||
void cmdFunctionLoad(int arg_cnt, char **args) {
|
void cmdFunctionLoad(int arg_cnt, char **args) {
|
||||||
loadConfigFromEEPROM();
|
loadConfigFromEEPROM();
|
||||||
// restoreState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1181,7 +1180,6 @@ int loadConfigFromEEPROM()
|
|||||||
|
|
||||||
void cmdFunctionReq(int arg_cnt, char **args) {
|
void cmdFunctionReq(int arg_cnt, char **args) {
|
||||||
mqttConfigRequest(arg_cnt, args);
|
mqttConfigRequest(arg_cnt, args);
|
||||||
// restoreState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2097,7 +2095,7 @@ configLocked--;
|
|||||||
}//if
|
}//if
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// Legacy Thermostat code below - to be moved in module /////
|
||||||
void thermoRelay(int pin, bool on)
|
void thermoRelay(int pin, bool on)
|
||||||
{
|
{
|
||||||
int thermoPin = abs(pin);
|
int thermoPin = abs(pin);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
#define TIMEOUT_REINIT 5000UL
|
#define TIMEOUT_REINIT 5000UL
|
||||||
#define TIMEOUT_RETAIN 5000UL
|
#define TIMEOUT_RETAIN 5000UL
|
||||||
#define INTERVAL_1W 5000UL
|
#define INTERVAL_1W 5000UL
|
||||||
#define PERIOD_THERMOSTAT_FAILED (500 * 1000UL)>>8
|
#define PERIOD_THERMOSTAT_FAILED (600 * 1000UL)>>8
|
||||||
|
|
||||||
//#define T_ATTEMPTS 200
|
//#define T_ATTEMPTS 200
|
||||||
//#define IET_TEMP 0
|
//#define IET_TEMP 0
|
||||||
|
|||||||
Reference in New Issue
Block a user