mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 03:39:49 +03:00
Cumulative changes/pre-release
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#-DW5500_CS_PIN=53
|
#-DW5500_CS_PIN=53
|
||||||
-DDMX_SMOOTH
|
-DDMX_SMOOTH
|
||||||
-DSYSLOG_ENABLE
|
-DSYSLOG_ENABLE
|
||||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||||
-DARTNET_ENABLE
|
-DARTNET_ENABLE
|
||||||
-DOTA
|
-DOTA
|
||||||
-DSTATUSLED
|
-DSTATUSLED
|
||||||
|
|||||||
@@ -26,6 +26,10 @@
|
|||||||
#-DmodbusSerial=Serial1
|
#-DmodbusSerial=Serial1
|
||||||
#-DMODBUS_DEBUG
|
#-DMODBUS_DEBUG
|
||||||
|
|
||||||
|
#-DMODBUS_UART_RX_PIN=16
|
||||||
|
#-DMODBUS_UART_TX_PIN=17
|
||||||
|
#-DmodbusSerial=Serial2
|
||||||
|
|
||||||
# Use default pins for modbus UART
|
# Use default pins for modbus UART
|
||||||
#-DMODBUS_UART_RX_PIN=-1
|
#-DMODBUS_UART_RX_PIN=-1
|
||||||
#-DMODBUS_UART_TX_PIN=-1
|
#-DMODBUS_UART_TX_PIN=-1
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
-DTIMER_INT
|
-DTIMER_INT
|
||||||
#-DFLASH_OFFSET=-256
|
#-DFLASH_OFFSET=-256
|
||||||
|
|
||||||
# Serial parameters for LEGACY Modbus
|
# default MODBUS Serial parameters for LEGACY Modbus and MODBUS over IP
|
||||||
-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||||
|
|
||||||
#Set Logariphmic law for DMX channels bright
|
#Set Logariphmic law for DMX channels bright
|
||||||
-DBRIGHT_LOG
|
-DBRIGHT_LOG
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||||
-DAVR_DMXOUT_PIN=18
|
-DAVR_DMXOUT_PIN=18
|
||||||
-DSYSLOG_ENABLE
|
-DSYSLOG_ENABLE
|
||||||
-DWiz5100
|
-DWiz5100
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
-DWiz5500
|
-DWiz5500
|
||||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||||
-DAVR_DMXOUT_PIN=18
|
-DAVR_DMXOUT_PIN=18
|
||||||
-DSYSLOG_ENABLE
|
-DSYSLOG_ENABLE
|
||||||
#-DPID_DISABLE
|
#-DPID_DISABLE
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||||
#-DAVR_DMXOUT_PIN=18
|
#-DAVR_DMXOUT_PIN=18
|
||||||
-DDMX_DISABLE
|
-DDMX_DISABLE
|
||||||
-DMODBUS_DISABLE
|
-DMODBUS_DISABLE
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||||
#-DAVR_DMXOUT_PIN=18
|
#-DAVR_DMXOUT_PIN=18
|
||||||
-DDMX_DISABLE
|
-DDMX_DISABLE
|
||||||
-DMODBUS_DISABLE
|
-DMODBUS_DISABLE
|
||||||
#-DMBUS_DISABLE
|
-DMBUS_DISABLE
|
||||||
#-DOWIRE_DISABLE
|
#-DOWIRE_DISABLE
|
||||||
-DDHT_DISABLE
|
-DDHT_DISABLE
|
||||||
-DCOUNTER_DISABLE
|
-DCOUNTER_DISABLE
|
||||||
|
|||||||
BIN
compiled/m5stack/StartCounter.ino.bin
Normal file
BIN
compiled/m5stack/StartCounter.ino.bin
Normal file
Binary file not shown.
@@ -12,6 +12,8 @@ int abstractOut::isActive()
|
|||||||
case CMD_VOID:
|
case CMD_VOID:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
case CMD_ON: //trying (PWM ON set=0 issue)
|
||||||
|
return 1;
|
||||||
default:
|
default:
|
||||||
st.loadItem(item);
|
st.loadItem(item);
|
||||||
return st.getPercents255();
|
return st.getPercents255();
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ public:
|
|||||||
abstractOut(Item * _item):abstractCh(){item=_item;};
|
abstractOut(Item * _item):abstractCh(){item=_item;};
|
||||||
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) =0;
|
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) =0;
|
||||||
virtual int isActive();
|
virtual int isActive();
|
||||||
|
virtual bool isAllowed(itemCmd cmd){return true;};
|
||||||
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
||||||
virtual int getChanType(){return 0;}
|
virtual int getChanType(){return 0;}
|
||||||
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
||||||
|
|||||||
@@ -293,6 +293,19 @@ bool systemConfig::setConfigFlags(systemConfigFlags flags)
|
|||||||
return setConfigFlags(flags);
|
return setConfigFlags(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool systemConfig::getDHCPfallback()
|
||||||
|
{
|
||||||
|
systemConfigFlags flags = getConfigFlags();
|
||||||
|
return flags.dhcpFallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool systemConfig::setDHCPfallback(bool flag)
|
||||||
|
{
|
||||||
|
systemConfigFlags flags = getConfigFlags();
|
||||||
|
flags.dhcpFallback=flag;
|
||||||
|
return setConfigFlags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
bool systemConfig::getLoadHTTPConfig()
|
bool systemConfig::getLoadHTTPConfig()
|
||||||
{
|
{
|
||||||
systemConfigFlags flags = getConfigFlags();
|
systemConfigFlags flags = getConfigFlags();
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ class systemConfig {
|
|||||||
bool saveETAG();
|
bool saveETAG();
|
||||||
bool loadETAG();
|
bool loadETAG();
|
||||||
|
|
||||||
|
bool getDHCPfallback();
|
||||||
|
bool setDHCPfallback(bool flag);
|
||||||
|
|
||||||
systemConfigFlags getConfigFlags();
|
systemConfigFlags getConfigFlags();
|
||||||
bool setConfigFlags(systemConfigFlags flags);
|
bool setConfigFlags(systemConfigFlags flags);
|
||||||
|
|
||||||
|
|||||||
@@ -541,9 +541,9 @@ void setupIpmodbus(){
|
|||||||
// Calculate Modbus RTU character timeout and frame delay
|
// Calculate Modbus RTU character timeout and frame delay
|
||||||
byte bits = // number of bits per character (11 in default Modbus RTU settings)
|
byte bits = // number of bits per character (11 in default Modbus RTU settings)
|
||||||
1 + // start bit
|
1 + // start bit
|
||||||
(((MODBUS_DIMMER_PARAM & 0x06) >> 1) + 5) + // data bits
|
(((MODBUS_SERIAL_PARAM & 0x06) >> 1) + 5) + // data bits
|
||||||
(((MODBUS_DIMMER_PARAM & 0x08) >> 3) + 1); // stop bits
|
(((MODBUS_SERIAL_PARAM & 0x08) >> 3) + 1); // stop bits
|
||||||
if (((MODBUS_DIMMER_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present)
|
if (((MODBUS_SERIAL_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present)
|
||||||
//bits = 11;
|
//bits = 11;
|
||||||
|
|
||||||
int T = ((unsigned long)bits * 1000000UL) / MODBUS_SERIAL_BAUD; // time to send 1 character over serial in microseconds
|
int T = ((unsigned long)bits * 1000000UL) / MODBUS_SERIAL_BAUD; // time to send 1 character over serial in microseconds
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ int txt2subItem(char *payload) {
|
|||||||
if (!payload || !strlen(payload)) return S_NOTFOUND;
|
if (!payload || !strlen(payload)) return S_NOTFOUND;
|
||||||
// Check for command
|
// Check for command
|
||||||
if (strcmp_P(payload, SET_P) == 0) cmd = S_SET;
|
if (strcmp_P(payload, SET_P) == 0) cmd = S_SET;
|
||||||
//else if (strcmp_P(payload, ESET_P) == 0) cmd = S_ESET;
|
else if (strcmp_P(payload, CTRL_P) == 0) cmd = S_CTRL;
|
||||||
else if (strcmp_P(payload, CMD_P) == 0) cmd = S_CMD;
|
else if (strcmp_P(payload, CMD_P) == 0) cmd = S_CMD;
|
||||||
else if (strcmp_P(payload, MODE_P) == 0) cmd = S_MODE;
|
else if (strcmp_P(payload, MODE_P) == 0) cmd = S_MODE;
|
||||||
else if (strcmp_P(payload, HSV_P) == 0) cmd = S_HSV;
|
else if (strcmp_P(payload, HSV_P) == 0) cmd = S_HSV;
|
||||||
@@ -326,7 +326,7 @@ uint32_t Item::getFlag (uint32_t flag)
|
|||||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||||
if (itemCmd && (itemCmd->type == aJson_Int))
|
if (itemCmd && (itemCmd->type == aJson_Int))
|
||||||
{
|
{
|
||||||
return itemCmd->valueint & flag & FLAG_MASK;
|
return (uint32_t) itemCmd->valueint & flag & FLAG_MASK;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -572,7 +572,12 @@ long int Item::limitSetValue()
|
|||||||
int Item::Ctrl(char * payload, char * subItem)
|
int Item::Ctrl(char * payload, char * subItem)
|
||||||
{
|
{
|
||||||
if (!payload) return 0;
|
if (!payload) return 0;
|
||||||
|
int fr = freeRam();
|
||||||
|
if (fr < minimalMemory)
|
||||||
|
{
|
||||||
|
errorSerial<<F("CTRL/txt: OutOfMemory: ")<<fr<<endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int suffixCode = 0;
|
int suffixCode = 0;
|
||||||
|
|
||||||
@@ -741,51 +746,54 @@ bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Main routine to control Item
|
|
||||||
//Return values
|
|
||||||
// 1 complete
|
|
||||||
// 3 complete, no action, target reached
|
|
||||||
// -3 ignored
|
|
||||||
// -1 system error
|
|
||||||
// -4 invalid argument
|
|
||||||
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t time=millis();
|
int Item::isScheduled()
|
||||||
int suffixCode = cmd.getSuffix();
|
{
|
||||||
bool operation = isNotRetainingStatus();
|
aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
||||||
|
if (timestampObj && (timestampObj->subtype > 0))
|
||||||
if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem))
|
{
|
||||||
subItem = defaultSubItem; /// possible problem here with truncated default
|
return timestampObj->subtype;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!suffixCode && subItem && strlen(subItem))
|
int Item::scheduleOppositeCommand(itemCmd cmd)
|
||||||
{
|
{
|
||||||
suffixCode = retrieveCode(&subItem);
|
itemCmd nextCmd=cmd;
|
||||||
if (!cmd.getSuffix()) cmd.setSuffix(suffixCode);
|
|
||||||
}
|
switch (cmd.getCmd()){
|
||||||
|
case CMD_XON: nextCmd.Cmd(CMD_XOFF);
|
||||||
|
break;
|
||||||
|
case CMD_XOFF: nextCmd.Cmd(CMD_XON);
|
||||||
|
break;
|
||||||
|
case CMD_ON: nextCmd.Cmd(CMD_OFF);
|
||||||
|
break;
|
||||||
|
case CMD_OFF: nextCmd.Cmd(CMD_ON);
|
||||||
|
break;
|
||||||
|
case CMD_ENABLE: nextCmd.Cmd(CMD_DISABLE);
|
||||||
|
break;
|
||||||
|
case CMD_DISABLE: nextCmd.Cmd(CMD_ENABLE);
|
||||||
|
break;
|
||||||
|
case CMD_FREEZE: nextCmd.Cmd(CMD_UNFREEZE);
|
||||||
|
break;
|
||||||
|
case CMD_UNFREEZE: nextCmd.Cmd(CMD_FREEZE);
|
||||||
|
break;
|
||||||
|
case CMD_HALT: nextCmd.Cmd(CMD_RESTORE);
|
||||||
|
break;
|
||||||
|
case CMD_RESTORE: nextCmd.Cmd(CMD_HALT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
debugSerial<<F("CTRL: Schedule cmd ")<<nextCmd.getCmd()<<F(" for (ms):")<<nextCmd.getInt()<<endl;
|
||||||
|
scheduleCommand(nextCmd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Item::scheduleCommand(itemCmd cmd)
|
||||||
|
{
|
||||||
|
if (!itemArr) return 0;
|
||||||
|
|
||||||
if (!suffixCode && defaultSuffixCode)
|
|
||||||
{
|
|
||||||
suffixCode = defaultSuffixCode;
|
|
||||||
if (!cmd.getSuffix()) cmd.setSuffix(suffixCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int fr = freeRam();
|
|
||||||
|
|
||||||
debugSerial<<F("RAM=")<<fr<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItem<<F(" ");
|
|
||||||
if (fr < 200)
|
|
||||||
{
|
|
||||||
errorSerial<<F("OutOfMemory!\n")<<endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
cmd.debugOut();
|
|
||||||
//debugSerial<<endl;
|
|
||||||
if (subItem && subItem[0] == '$') {debugSerial<<F("Skipped homie stuff")<<endl;return -4; }
|
|
||||||
if (!itemArr) return -1;
|
|
||||||
|
|
||||||
/// DELAYED COMMANDS processing
|
|
||||||
if (suffixCode == S_DELAYED)
|
|
||||||
{
|
|
||||||
for (int i = aJson.getArraySize(itemArr); i <= I_TIMESTAMP; i++)
|
for (int i = aJson.getArraySize(itemArr); i <= I_TIMESTAMP; i++)
|
||||||
aJson.addItemToArray(itemArr, aJson.createNull());
|
aJson.addItemToArray(itemArr, aJson.createNull());
|
||||||
|
|
||||||
@@ -807,6 +815,56 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
//Main routine to control Item
|
||||||
|
//Return values
|
||||||
|
// 1 complete
|
||||||
|
// 3 complete, no action, target reached
|
||||||
|
// -3 ignored
|
||||||
|
// -1 system error
|
||||||
|
// -4 invalid argument
|
||||||
|
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||||
|
{
|
||||||
|
int fr = freeRam();
|
||||||
|
if (fr < minimalMemory)
|
||||||
|
{
|
||||||
|
errorSerial<<F("CTRL: OutOfMemory: ")<<fr<<endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint32_t time=millis();
|
||||||
|
int suffixCode = cmd.getSuffix();
|
||||||
|
bool operation = isNotRetainingStatus();
|
||||||
|
|
||||||
|
if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem))
|
||||||
|
subItem = defaultSubItem; /// possible problem here with truncated default
|
||||||
|
|
||||||
|
if (!suffixCode && subItem && strlen(subItem))
|
||||||
|
{
|
||||||
|
suffixCode = retrieveCode(&subItem);
|
||||||
|
if (!cmd.getSuffix()) cmd.setSuffix(suffixCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!suffixCode && defaultSuffixCode)
|
||||||
|
{
|
||||||
|
suffixCode = defaultSuffixCode;
|
||||||
|
if (!cmd.getSuffix()) cmd.setSuffix(suffixCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
debugSerial<<F("CTRL: RAM=")<<fr<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItem<<F(" ");
|
||||||
|
|
||||||
|
cmd.debugOut();
|
||||||
|
//debugSerial<<endl;
|
||||||
|
if (subItem && subItem[0] == '$') {debugSerial<<F("Skipped homie stuff")<<endl;return -4; }
|
||||||
|
if (!itemArr) return -1;
|
||||||
|
|
||||||
|
/// DELAYED COMMANDS processing
|
||||||
|
if (suffixCode == S_DELAYED)
|
||||||
|
{
|
||||||
|
return scheduleCommand(cmd);
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
int8_t chActive = -1;
|
int8_t chActive = -1;
|
||||||
@@ -827,6 +885,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
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
|
||||||
|
if (subItem) {debugSerial<<F("CTRL: Unknown suffix")<<endl; break;}; // if some unknown suffix
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
scale100=true; //openHab topic format
|
scale100=true; //openHab topic format
|
||||||
chActive=(isActive()>0);
|
chActive=(isActive()>0);
|
||||||
@@ -950,11 +1009,12 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
{
|
{
|
||||||
if (fr<350)
|
if (fr<350)
|
||||||
{
|
{
|
||||||
errorSerial<<F("Not enough memory for group operation")<<endl;
|
errorSerial<<F("CTRL: Not enough memory for group operation")<<endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (allowRecursion && itemArg->type == aJson_Array && operation)
|
if (allowRecursion && itemArg->type == aJson_Array && operation)
|
||||||
{
|
{
|
||||||
|
chActive=(isActive()>0);
|
||||||
digGroup(itemArg,&cmd,subItem);
|
digGroup(itemArg,&cmd,subItem);
|
||||||
}
|
}
|
||||||
res=1;
|
res=1;
|
||||||
@@ -965,7 +1025,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_RESTORE: // individual for group members
|
case CMD_RESTORE: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_HALT: //previous command was HALT ?
|
case CMD_HALT: //previous command was HALT ?
|
||||||
debugSerial << F("Restored from:") << t << endl;
|
if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
||||||
|
debugSerial << F("CTRL: Restored from:") << t << endl;
|
||||||
cmd.loadItemDef(this);
|
cmd.loadItemDef(this);
|
||||||
cmd.Cmd(CMD_ON); //turning on
|
cmd.Cmd(CMD_ON); //turning on
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
@@ -978,20 +1039,30 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_XOFF: // individual for group members
|
case CMD_XOFF: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_XON: //previous command was CMD_XON ?
|
case CMD_XON: //previous command was CMD_XON ?
|
||||||
debugSerial << F("Turned off from:") << t << endl;
|
if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
||||||
|
debugSerial << F("CTRL: Turned off from:") << t << endl;
|
||||||
cmd.Cmd(CMD_OFF); //turning Off
|
cmd.Cmd(CMD_OFF); //turning Off
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl;
|
debugSerial << F("CTRL: XOFF skipped. Prev cmd:") << t <<endl;
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
chActive=(isActive()>0);
|
|
||||||
|
if (!getFlag(FLAG_DISABLED))
|
||||||
|
{
|
||||||
|
if (chActive == -1) chActive=(isActive()>0);
|
||||||
|
|
||||||
|
if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
||||||
|
|
||||||
|
|
||||||
if (!chActive) //if channel was'nt active before CMD_XON
|
if (!chActive) //if channel was'nt active before CMD_XON
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
cmd.loadItemDef(this);
|
cmd.loadItemDef(this);
|
||||||
cmd.Cmd(CMD_ON);
|
cmd.Cmd(CMD_ON);
|
||||||
command2Set=CMD_XON;
|
command2Set=CMD_XON;
|
||||||
@@ -999,13 +1070,21 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugSerial<<F("XON:Already Active\n");
|
debugSerial<<F("CTRL: XON:Already Active\n");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugSerial<<F("CTRL: XON: Disabled\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
chActive=(isActive()>0);
|
if (chActive == -1) chActive=(isActive()>0);
|
||||||
if (chActive) //if channel was active before CMD_HALT
|
if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
||||||
|
if (chActive) //if channel was active before CMD_HALT /// HERE bug - if cmd == On but 0 = active
|
||||||
{
|
{
|
||||||
cmd.Cmd(CMD_OFF);
|
cmd.Cmd(CMD_OFF);
|
||||||
command2Set=CMD_HALT;
|
command2Set=CMD_HALT;
|
||||||
@@ -1013,7 +1092,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugSerial<<F("HALT:Already Inactive\n");
|
debugSerial<<F("CTRL: HALT:Already Inactive\n");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1028,7 +1107,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
{ // NON GROUP part
|
{ // NON GROUP part
|
||||||
if (chActive<0) chActive = (isActive()>0);
|
if (chActive<0) chActive = (isActive()>0);
|
||||||
toExecute=chActive || toExecute; // Execute if active
|
toExecute=chActive || toExecute; // Execute if active
|
||||||
debugSerial<<F("Active:")<<chActive<<F( " Exec:")<<toExecute<<endl;
|
debugSerial<<F("CTRL: Active:")<<chActive<<F( " Exec:")<<toExecute<<endl;
|
||||||
if (subItem)
|
if (subItem)
|
||||||
{
|
{
|
||||||
//Check if subitem is some sort of command
|
//Check if subitem is some sort of command
|
||||||
@@ -1040,7 +1119,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
{
|
{
|
||||||
if (subitemCmd != prevCmd)
|
if (subitemCmd != prevCmd)
|
||||||
{
|
{
|
||||||
debugSerial<<F("Ignored, channel cmd=")<<prevCmd<<endl;
|
debugSerial<<F("CTRL: Ignored, channel cmd=")<<prevCmd<<endl;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
subItem=NULL;
|
subItem=NULL;
|
||||||
@@ -1059,7 +1138,10 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_RESTORE: // individual for group members
|
case CMD_RESTORE: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_HALT: //previous command was HALT ?
|
case CMD_HALT: //previous command was HALT ?
|
||||||
debugSerial << F("Restored from:") << t << endl;
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
|
||||||
|
debugSerial << F("CTRL: Restored from:") << t << endl;
|
||||||
cmd.loadItemDef(this);
|
cmd.loadItemDef(this);
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
if (itemType == CH_THERMO) cmd.Cmd(CMD_AUTO); ////
|
if (itemType == CH_THERMO) cmd.Cmd(CMD_AUTO); ////
|
||||||
@@ -1074,33 +1156,52 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_XOFF: // individual for group members
|
case CMD_XOFF: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_XON: //previous command was CMD_XON ?
|
case CMD_XON: //previous command was CMD_XON ?
|
||||||
debugSerial << F("Turned off from:") << t << endl;
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
debugSerial << F("CTRL: Turned off from:") << t << endl;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
cmd.Cmd(CMD_OFF); //turning Off
|
cmd.Cmd(CMD_OFF); //turning Off
|
||||||
|
clearFlag(FLAG_XON);
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl;
|
debugSerial << F("CTRL: XOFF skipped. Prev cmd:") << t <<endl;
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
if (!chActive) //if channel was'nt active before CMD_XON
|
if (!getFlag(FLAG_DISABLED))
|
||||||
{
|
{
|
||||||
cmd.loadItemDef(this);
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
cmd.Cmd(CMD_ON);
|
scheduleOppositeCommand(cmd);
|
||||||
command2Set=CMD_XON;
|
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
if (!chActive) //if channel was'nt active before CMD_XON
|
||||||
toExecute=true;
|
{
|
||||||
}
|
|
||||||
else
|
cmd.loadItemDef(this);
|
||||||
{
|
cmd.Cmd(CMD_ON);
|
||||||
debugSerial<<F("XON:Already Active\n");
|
command2Set=CMD_XON;
|
||||||
return 3;
|
setFlag(FLAG_XON);
|
||||||
}
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
|
toExecute=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugSerial<<F("CTRL: XON:Already Active\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugSerial<<F("CTRL: XON: Disabled\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
if (chActive) //if channel was active before CMD_HALT
|
if (chActive) //if channel was active before CMD_HALT
|
||||||
{
|
{
|
||||||
cmd.Cmd(CMD_OFF);
|
cmd.Cmd(CMD_OFF);
|
||||||
@@ -1110,7 +1211,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugSerial<<F("HALT:Already Inactive\n");
|
debugSerial<<F("CTRL: HALT:Already Inactive\n");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1123,11 +1224,18 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
|
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
|
||||||
|
|
||||||
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
|
|
||||||
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
|
||||||
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
||||||
{
|
{
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
@@ -1135,7 +1243,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
if (chActive)
|
if (chActive)
|
||||||
{
|
{
|
||||||
debugSerial<<F("ON:Already Active\n");
|
debugSerial<<F("CTRL: ON:Already Active\n");
|
||||||
setCmd(CMD_ON);
|
setCmd(CMD_ON);
|
||||||
SendStatus(FLAG_COMMAND | FLAG_SEND_DEFFERED);
|
SendStatus(FLAG_COMMAND | FLAG_SEND_DEFFERED);
|
||||||
return 3;
|
return 3;
|
||||||
@@ -1163,6 +1271,43 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_UP:
|
case CMD_UP:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_ENABLE:
|
||||||
|
//clearFlag(FLAG_DISABLED); //saveItem have this
|
||||||
|
status2Send |= FLAG_FLAGS;
|
||||||
|
toExecute=true;
|
||||||
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
|
if (allowRecursion && cmd.isValue() && (getFlag(FLAG_DISABLED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_DISABLE:
|
||||||
|
//setFlag(FLAG_DISABLED); //saveItem have this
|
||||||
|
status2Send |= FLAG_FLAGS;
|
||||||
|
toExecute=true;
|
||||||
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!getFlag(FLAG_DISABLED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_UNFREEZE:
|
||||||
|
//clearFlag(FLAG_DISABLED); //saveItem have this
|
||||||
|
status2Send = FLAG_FLAGS;
|
||||||
|
toExecute=true;
|
||||||
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (getFlag(FLAG_FREEZED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_FREEZE:
|
||||||
|
//setFlag(FLAG_DISABLED); //saveItem have this
|
||||||
|
status2Send = FLAG_FLAGS;
|
||||||
|
command2Set = 0;
|
||||||
|
toExecute=true;
|
||||||
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
|
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!getFlag(FLAG_FREEZED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
|
scheduleOppositeCommand(cmd);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (cmd.isCommand()) status2Send |= FLAG_COMMAND;
|
if (cmd.isCommand()) status2Send |= FLAG_COMMAND;
|
||||||
if (cmd.isValue()) status2Send |= FLAG_PARAMETERS;
|
if (cmd.isValue()) status2Send |= FLAG_PARAMETERS;
|
||||||
@@ -1170,110 +1315,145 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
} //Switch commands
|
} //Switch commands
|
||||||
} // NO GROUP
|
} // NO GROUP
|
||||||
if (invalidArgument) return -4;
|
if (invalidArgument) return -4;
|
||||||
// UPDATE internal variables
|
|
||||||
if (status2Send) cmd.saveItem(this,status2Send);
|
|
||||||
//debugSerial<<F("sts:")<<status2Send<<endl;
|
|
||||||
|
|
||||||
if (driver) //New style modular code
|
if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
||||||
{
|
|
||||||
res = driver->Ctrl(cmd, subItem, toExecute);
|
|
||||||
if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE;
|
|
||||||
//if (res==-1) status2Send=0; ///////not working
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
switch (itemType) {
|
// UPDATE internal variables
|
||||||
/// rest of Legacy monolite core code (to be refactored ) BEGIN ///
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
case CH_RELAY:
|
//debugSerial<<F("sts:")<<status2Send<<endl;
|
||||||
{
|
|
||||||
short iaddr=getArg();
|
|
||||||
short icmd =cmd.getCmd();
|
|
||||||
|
|
||||||
if (iaddr)
|
if (driver) //New style modular code
|
||||||
{
|
{
|
||||||
int k;
|
res = driver->Ctrl(cmd, subItem, toExecute);
|
||||||
short inverse = 0;
|
if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE;
|
||||||
|
//if (res==-1) status2Send=0; ///////not working
|
||||||
if (iaddr < 0) {
|
if (status2Send & FLAG_FLAGS) res =1; //ENABLE & DISABLE processed by core
|
||||||
iaddr = -iaddr;
|
}
|
||||||
inverse = 1;
|
else
|
||||||
}
|
{
|
||||||
if (iaddr <= (short) PINS_COUNT && iaddr>0)
|
switch (itemType) {
|
||||||
{
|
/// rest of Legacy monolite core code (to be refactored ) BEGIN ///
|
||||||
pinMode(iaddr, OUTPUT);
|
case CH_RELAY:
|
||||||
|
if (cmd.isCommand())
|
||||||
if (inverse)
|
|
||||||
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? LOW : HIGH));
|
|
||||||
else
|
|
||||||
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? HIGH : LOW));
|
|
||||||
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
|
||||||
res=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CH_THERMO:
|
|
||||||
switch (suffixCode)
|
|
||||||
{
|
|
||||||
case S_VAL:
|
|
||||||
//S_NOTFOUND:
|
|
||||||
{
|
|
||||||
thermostatStore tStore;
|
|
||||||
tStore.asint=getExt();
|
|
||||||
if (!tStore.timestamp16) mqttClient.publish("/alarmoff/snsr", itemArr->name);
|
|
||||||
tStore.tempX100=cmd.getFloat()*100.; //Save measurement
|
|
||||||
tStore.timestamp16=millisNZ(8) & 0xFFFF; //And timestamp
|
|
||||||
debugSerial<<F(" T:")<<tStore.tempX100<<F(" TS:")<<tStore.timestamp16<<endl;
|
|
||||||
setExt(tStore.asint);
|
|
||||||
res=1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case S_SET:
|
|
||||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
|
||||||
res=1;
|
|
||||||
//st.saveItem(this);
|
|
||||||
break;
|
|
||||||
case S_CMD:
|
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
|
||||||
res=1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MODBUS_DISABLE
|
|
||||||
case CH_MODBUS:
|
|
||||||
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue()))
|
|
||||||
{
|
{
|
||||||
int vol;
|
|
||||||
if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())<MIN_VOLUME && vol>=0)
|
|
||||||
|
short iaddr=getArg();
|
||||||
|
short icmd =cmd.getCmd();
|
||||||
|
|
||||||
|
if (iaddr)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
short inverse = 0;
|
||||||
|
|
||||||
|
if (iaddr < 0) {
|
||||||
|
iaddr = -iaddr;
|
||||||
|
inverse = 1;
|
||||||
|
}
|
||||||
|
if (iaddr <= (short) PINS_COUNT && iaddr>0)
|
||||||
{
|
{
|
||||||
cmd.setPercents(INIT_VOLUME);
|
pinMode(iaddr, OUTPUT);
|
||||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
|
||||||
};
|
|
||||||
|
|
||||||
res=modbusDimmerSet(cmd);
|
switch (icmd){
|
||||||
|
case CMD_AUTO:
|
||||||
|
case CMD_COOL:
|
||||||
|
case CMD_ON:
|
||||||
|
case CMD_DRY:
|
||||||
|
case CMD_FAN:
|
||||||
|
case CMD_XON:
|
||||||
|
digitalWrite(iaddr, k = (inverse) ? LOW : HIGH);
|
||||||
|
break;
|
||||||
|
case CMD_OFF:
|
||||||
|
case CMD_HALT:
|
||||||
|
case CMD_XOFF:
|
||||||
|
digitalWrite(iaddr, k = (inverse) ? HIGH : LOW);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (inverse)
|
||||||
|
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? LOW : HIGH));
|
||||||
|
else
|
||||||
|
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? HIGH : LOW));
|
||||||
|
|
||||||
|
*/
|
||||||
|
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
||||||
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
|
res=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case CH_VC:
|
|
||||||
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetFan(cmd);
|
|
||||||
break;
|
|
||||||
case CH_VCTEMP:
|
|
||||||
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetHeat(cmd);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
/// rest of Legacy monolite core code (to be refactored ) END ///
|
|
||||||
|
|
||||||
} //switch
|
case CH_THERMO:
|
||||||
} //else (nodriver)
|
switch (suffixCode)
|
||||||
|
{
|
||||||
|
case S_VAL:
|
||||||
|
//S_NOTFOUND:
|
||||||
|
{
|
||||||
|
thermostatStore tStore;
|
||||||
|
tStore.asint=getExt();
|
||||||
|
if (!tStore.timestamp16) mqttClient.publish("/alarmoff/snsr", itemArr->name);
|
||||||
|
tStore.tempX100=cmd.getFloat()*100.; //Save measurement
|
||||||
|
tStore.timestamp16=millisNZ(8) & 0xFFFF; //And timestamp
|
||||||
|
debugSerial<<F(" T:")<<tStore.tempX100<<F(" TS:")<<tStore.timestamp16<<endl;
|
||||||
|
setExt(tStore.asint);
|
||||||
|
res=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case S_SET:
|
||||||
|
status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
||||||
|
res=1;
|
||||||
|
//st.saveItem(this);
|
||||||
|
break;
|
||||||
|
case S_CMD:
|
||||||
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
|
res=1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
//update command for HALT & XON and send MQTT status
|
|
||||||
if (command2Set) setCmd(command2Set | FLAG_COMMAND);
|
|
||||||
if (operation) SendStatus(status2Send);
|
|
||||||
|
|
||||||
debugSerial<<F("Ctrl Res:")<<res<<F(" time:")<<millis()-time<<endl;
|
#ifndef MODBUS_DISABLE
|
||||||
|
case CH_MODBUS:
|
||||||
|
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue()))
|
||||||
|
{
|
||||||
|
int vol;
|
||||||
|
if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())<MIN_VOLUME && vol>=0)
|
||||||
|
{
|
||||||
|
cmd.setPercents(INIT_VOLUME);
|
||||||
|
status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
||||||
|
};
|
||||||
|
|
||||||
|
res=modbusDimmerSet(cmd);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CH_VC:
|
||||||
|
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetFan(cmd);
|
||||||
|
break;
|
||||||
|
case CH_VCTEMP:
|
||||||
|
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetHeat(cmd);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
/// rest of Legacy monolite core code (to be refactored ) END ///
|
||||||
|
|
||||||
|
} //switch
|
||||||
|
|
||||||
|
} //else (nodriver)
|
||||||
|
|
||||||
|
//update command for HALT & XON and send MQTT status
|
||||||
|
if (command2Set) setCmd(command2Set | FLAG_COMMAND);
|
||||||
|
if (operation) SendStatus(status2Send);
|
||||||
|
} //alowed cmd
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorSerial<<F("CTRL: Command blocked by driver or channel frozen")<<endl;
|
||||||
|
if ((status2Send & FLAG_FLAGS) && operation)
|
||||||
|
{
|
||||||
|
cmd.saveItem(this,FLAG_FLAGS);
|
||||||
|
SendStatus(FLAG_FLAGS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debugSerial<<F("CTRL: Res:")<<res<<F(" time:")<<millis()-time<<endl;
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printActiveStatus(bool active)
|
void printActiveStatus(bool active)
|
||||||
@@ -1379,7 +1559,15 @@ if (timestampObj)
|
|||||||
|
|
||||||
if (remain <0 && abs(remain)< 0xFFFFFFFFUL/2)
|
if (remain <0 && abs(remain)< 0xFFFFFFFFUL/2)
|
||||||
{
|
{
|
||||||
SendStatusImmediate(st,FLAG_SEND_DELAYED);
|
int fr = freeRam();
|
||||||
|
SendStatusImmediate(st,FLAG_SEND_DELAYED);
|
||||||
|
|
||||||
|
if (fr < minimalMemory)
|
||||||
|
{
|
||||||
|
errorSerial<<F("CTRL/poll: OutOfMemory: ")<<fr<<endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Ctrl(itemCmd(ST_VOID,cmd));
|
Ctrl(itemCmd(ST_VOID,cmd));
|
||||||
timestampObj->subtype=0;
|
timestampObj->subtype=0;
|
||||||
}
|
}
|
||||||
@@ -1430,7 +1618,7 @@ void Item::sendDelayedStatus()
|
|||||||
int Item::SendStatus(int sendFlags) {
|
int Item::SendStatus(int sendFlags) {
|
||||||
if (sendFlags & FLAG_SEND_IMMEDIATE) sendFlags &= ~ (FLAG_SEND_IMMEDIATE | FLAG_SEND_DEFFERED);
|
if (sendFlags & FLAG_SEND_IMMEDIATE) sendFlags &= ~ (FLAG_SEND_IMMEDIATE | FLAG_SEND_DEFFERED);
|
||||||
if ((sendFlags & FLAG_SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
|
if ((sendFlags & FLAG_SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
|
||||||
setFlag(sendFlags & (FLAG_COMMAND | FLAG_PARAMETERS));
|
setFlag(sendFlags & (FLAG_COMMAND | FLAG_PARAMETERS | FLAG_FLAGS));
|
||||||
debugSerial<<F("Status deffered\n");
|
debugSerial<<F("Status deffered\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1438,7 +1626,7 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
{
|
{
|
||||||
itemCmd st(ST_VOID,CMD_VOID);
|
itemCmd st(ST_VOID,CMD_VOID);
|
||||||
st.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
st.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
||||||
sendFlags |= getFlag(FLAG_COMMAND | FLAG_PARAMETERS); //if some delayed status is pending
|
sendFlags |= getFlag(FLAG_COMMAND | FLAG_PARAMETERS | FLAG_FLAGS); //if some delayed status is pending
|
||||||
//debugSerial<<F("ssi:")<<sendFlags<<endl;
|
//debugSerial<<F("ssi:")<<sendFlags<<endl;
|
||||||
return SendStatusImmediate(st,sendFlags);
|
return SendStatusImmediate(st,sendFlags);
|
||||||
}
|
}
|
||||||
@@ -1462,10 +1650,11 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
case CMD_COOL:
|
case CMD_COOL:
|
||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
case CMD_ENABLE:
|
|
||||||
case CMD_DISABLE:
|
|
||||||
strcpy_P(cmdstr, ON_P);
|
strcpy_P(cmdstr, ON_P);
|
||||||
break;
|
break;
|
||||||
|
//case CMD_ENABLE:
|
||||||
|
//case CMD_DISABLE:
|
||||||
|
// break;
|
||||||
case CMD_OFF:
|
case CMD_OFF:
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
strcpy_P(cmdstr, OFF_P);
|
strcpy_P(cmdstr, OFF_P);
|
||||||
@@ -1487,7 +1676,7 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
|
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
{
|
{
|
||||||
if (!subItem)
|
if (!subItem )
|
||||||
{
|
{
|
||||||
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
||||||
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||||
@@ -1501,7 +1690,7 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
mqttClient.publish(addrstr, valstr, true);
|
mqttClient.publish(addrstr, valstr, true);
|
||||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
||||||
}
|
}
|
||||||
else if (sendFlags & FLAG_COMMAND)
|
else if ((sendFlags & FLAG_COMMAND) && (strlen(cmdstr)))
|
||||||
{
|
{
|
||||||
mqttClient.publish(addrstr, cmdstr, true);
|
mqttClient.publish(addrstr, cmdstr, true);
|
||||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
||||||
@@ -1584,12 +1773,12 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
case CMD_FAN:
|
case CMD_FAN:
|
||||||
strcpy_P(cmdstr, FAN_ONLY_P);
|
strcpy_P(cmdstr, FAN_ONLY_P);
|
||||||
break;
|
break;
|
||||||
case CMD_ENABLE:
|
//case CMD_ENABLE:
|
||||||
strcpy_P(cmdstr, ENABLE_P);
|
// strcpy_P(cmdstr, ENABLE_P);
|
||||||
break;
|
// break;
|
||||||
case CMD_DISABLE:
|
//case CMD_DISABLE:
|
||||||
strcpy_P(cmdstr, DISABLE_P);
|
// strcpy_P(cmdstr, DISABLE_P);
|
||||||
break;
|
// break;
|
||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
if (itemType == CH_THERMO) strcpy_P(cmdstr, AUTO_P);
|
if (itemType == CH_THERMO) strcpy_P(cmdstr, AUTO_P);
|
||||||
@@ -1617,6 +1806,43 @@ int Item::SendStatus(int sendFlags) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Send ctrl
|
||||||
|
if (sendFlags & FLAG_FLAGS)
|
||||||
|
{
|
||||||
|
if (getFlag(FLAG_DISABLED))
|
||||||
|
strcpy_P(cmdstr, DISABLE_P);
|
||||||
|
|
||||||
|
else if (getFlag(FLAG_FREEZED))
|
||||||
|
strcpy_P(cmdstr, FREEZE_P);
|
||||||
|
|
||||||
|
else strcpy_P(cmdstr, ENABLE_P);
|
||||||
|
|
||||||
|
|
||||||
|
//else strcpy_P(cmdstr, UNFREEZE_P);
|
||||||
|
|
||||||
|
|
||||||
|
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
||||||
|
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||||
|
if (subItem)
|
||||||
|
{
|
||||||
|
strncat(addrstr, "/", sizeof(addrstr)-1);
|
||||||
|
strncat(addrstr, subItem, sizeof(addrstr)-1);
|
||||||
|
}
|
||||||
|
strncat(addrstr, "/", sizeof(addrstr)-1);
|
||||||
|
strncat_P(addrstr, CTRL_P, sizeof(addrstr)-1);
|
||||||
|
|
||||||
|
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
||||||
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
|
{
|
||||||
|
mqttClient.publish(addrstr, cmdstr,true);
|
||||||
|
clearFlag(FLAG_FLAGS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFlag(sendFlags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1821,7 +2047,7 @@ int Item::VacomSetFan(itemCmd st) {
|
|||||||
//uint8_t j;//, result;
|
//uint8_t j;//, result;
|
||||||
//uint16_t data[1];
|
//uint16_t data[1];
|
||||||
|
|
||||||
modbusSerial.begin(9600, fmPar);
|
modbusSerial.begin(MODBUS_FM_BAUD, MODBUS_FM_PARAM);
|
||||||
node.begin(addr, modbusSerial);
|
node.begin(addr, modbusSerial);
|
||||||
|
|
||||||
if (val) {
|
if (val) {
|
||||||
@@ -1866,7 +2092,7 @@ int addr;
|
|||||||
}
|
}
|
||||||
modbusBusy = 1;
|
modbusBusy = 1;
|
||||||
|
|
||||||
modbusSerial.begin(9600, fmPar);
|
modbusSerial.begin(MODBUS_FM_BAUD, MODBUS_FM_PARAM);
|
||||||
node.begin(addr, modbusSerial);
|
node.begin(addr, modbusSerial);
|
||||||
|
|
||||||
uint16_t regval;
|
uint16_t regval;
|
||||||
@@ -1903,7 +2129,7 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint
|
|||||||
};
|
};
|
||||||
modbusBusy = 1;
|
modbusBusy = 1;
|
||||||
|
|
||||||
modbusSerial.begin(MODBUS_SERIAL_BAUD, dimPar);
|
modbusSerial.begin(MODBUS_SERIAL_BAUD, MODBUS_SERIAL_PARAM);
|
||||||
node.begin(addr, modbusSerial);
|
node.begin(addr, modbusSerial);
|
||||||
uint8_t t;
|
uint8_t t;
|
||||||
switch (_mask) {
|
switch (_mask) {
|
||||||
@@ -1971,7 +2197,7 @@ int Item::checkFM() {
|
|||||||
// aJson.addStringToObject(out,"type", "rect");
|
// aJson.addStringToObject(out,"type", "rect");
|
||||||
|
|
||||||
|
|
||||||
modbusSerial.begin(9600, fmPar);
|
modbusSerial.begin(MODBUS_FM_BAUD, MODBUS_FM_PARAM);
|
||||||
node.begin(getArg(), modbusSerial);
|
node.begin(getArg(), modbusSerial);
|
||||||
|
|
||||||
|
|
||||||
@@ -2090,7 +2316,7 @@ int Item::checkModbusDimmer() {
|
|||||||
|
|
||||||
//node.setSlave(addr);
|
//node.setSlave(addr);
|
||||||
|
|
||||||
modbusSerial.begin(MODBUS_SERIAL_BAUD, dimPar);
|
modbusSerial.begin(MODBUS_SERIAL_BAUD, MODBUS_SERIAL_PARAM);
|
||||||
node.begin(addr, modbusSerial);
|
node.begin(addr, modbusSerial);
|
||||||
|
|
||||||
switch (_regType) {
|
switch (_regType) {
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ class Item
|
|||||||
inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
|
inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
|
||||||
inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
|
inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
|
||||||
int scheduleCommand(itemCmd cmd);
|
int scheduleCommand(itemCmd cmd);
|
||||||
|
int scheduleOppositeCommand(itemCmd cmd);
|
||||||
int isScheduled();
|
int isScheduled();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
|
|||||||
case CH_PWM:
|
case CH_PWM:
|
||||||
case CH_VC:
|
case CH_VC:
|
||||||
case CH_MODBUS:
|
case CH_MODBUS:
|
||||||
|
//case CH_RELAY:
|
||||||
//case CH_GROUP:
|
//case CH_GROUP:
|
||||||
return ST_PERCENTS255;
|
return ST_PERCENTS255;
|
||||||
break;
|
break;
|
||||||
@@ -1115,13 +1116,23 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
|
|||||||
|
|
||||||
case CMD_ENABLE:
|
case CMD_ENABLE:
|
||||||
item->clearFlag(FLAG_DISABLED);
|
item->clearFlag(FLAG_DISABLED);
|
||||||
|
item->clearFlag(FLAG_FREEZED);
|
||||||
break;
|
break;
|
||||||
|
case CMD_FREEZE:
|
||||||
|
item->setFlag(FLAG_FREEZED);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_UNFREEZE:
|
||||||
|
item->clearFlag(FLAG_FREEZED);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (optionsFlag & FLAG_COMMAND)
|
if (optionsFlag & FLAG_COMMAND)
|
||||||
switch (cmd.cmdCode)
|
switch (cmd.cmdCode)
|
||||||
{
|
{
|
||||||
case CMD_DISABLE:
|
case CMD_DISABLE:
|
||||||
case CMD_ENABLE:
|
case CMD_ENABLE:
|
||||||
|
case CMD_FREEZE:
|
||||||
|
case CMD_UNFREEZE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
item->setCmd(cmd.cmdCode);
|
item->setCmd(cmd.cmdCode);
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ typedef char cmdstr[9];
|
|||||||
const cmdstr commands_P[] PROGMEM =
|
const cmdstr commands_P[] PROGMEM =
|
||||||
{
|
{
|
||||||
"","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE",
|
"","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE",
|
||||||
"HEAT","COOL","AUTO","FAN_ONLY","DRY","STOP","HIGH","MEDIUM","LOW","ENABLE","DISABLE",
|
"ENABLE","DISABLE","UNFREEZE","FREEZE",
|
||||||
"TRUE","FALSE","RGB","HSV"
|
"AUTO","FAN_ONLY",
|
||||||
|
"HIGH","MEDIUM","LOW",
|
||||||
|
"HEAT","COOL","DRY","STOP","RGB","HSV"
|
||||||
};
|
};
|
||||||
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
||||||
|
|
||||||
@@ -41,20 +43,24 @@ const cmdstr commands_P[] PROGMEM =
|
|||||||
#define CMD_XOFF 7 /// OFF only if was previously turned on by CMD_XON
|
#define CMD_XOFF 7 /// OFF only if was previously turned on by CMD_XON
|
||||||
#define CMD_UP 8 /// increase
|
#define CMD_UP 8 /// increase
|
||||||
#define CMD_DN 9 /// decrease
|
#define CMD_DN 9 /// decrease
|
||||||
#define CMD_HEAT 0xa /// Thermostat/AC set to HEATing mode
|
|
||||||
#define CMD_COOL 0xb /// Thermostat/AC set to COOLing mode
|
#define CMD_ENABLE 0xa /// for PID regulator and XON/XOFF - chan limitation
|
||||||
#define CMD_AUTO 0xc /// Thermostat/AC set to Auto mode
|
#define CMD_DISABLE 0xb /// for PID regulator
|
||||||
#define CMD_FAN 0xd /// AC set to Fan-only mode
|
#define CMD_UNFREEZE 0xc /// Aliase for ON
|
||||||
#define CMD_DRY 0xe /// AC set to Dry mode
|
#define CMD_FREEZE 0xd /// Aliase for OFF
|
||||||
#define CMD_STOP 0xf /// stop dimming (for further use)
|
|
||||||
|
#define CMD_AUTO 0xe /// Thermostat/AC set to Auto mode
|
||||||
|
#define CMD_FAN 0xf /// AC set to Fan-only mode
|
||||||
|
|
||||||
#define CMD_HIGH 0x10 /// AC/Vent fan level HIGH
|
#define CMD_HIGH 0x10 /// AC/Vent fan level HIGH
|
||||||
#define CMD_MED 0x11 /// AC/Vent fan level MEDIUM
|
#define CMD_MED 0x11 /// AC/Vent fan level MEDIUM
|
||||||
#define CMD_LOW 0x12 /// AC/Vent fan level LOW
|
#define CMD_LOW 0x12 /// AC/Vent fan level LOW
|
||||||
#define CMD_ENABLE 0x13 /// for PID regulator
|
|
||||||
#define CMD_DISABLE 0x14 /// for PID regulator
|
#define CMD_HEAT 0x13 /// Thermostat/AC set to HEATing mode
|
||||||
#define CMD_TRUE 0x15 /// Aliase for ON
|
#define CMD_COOL 0x14 /// Thermostat/AC set to COOLing mode
|
||||||
#define CMD_FALSE 0x16 /// Aliase for OFF
|
#define CMD_DRY 0x15 /// AC set to Dry mode
|
||||||
|
#define CMD_STOP 0x16 /// stop dimming (for further use)
|
||||||
|
|
||||||
#define CMD_RGB 0x17
|
#define CMD_RGB 0x17
|
||||||
#define CMD_HSV 0x18
|
#define CMD_HSV 0x18
|
||||||
|
|
||||||
@@ -78,7 +84,7 @@ const cmdstr commands_P[] PROGMEM =
|
|||||||
#define FLAG_ACTION_IN_PROCESS 0x8000UL
|
#define FLAG_ACTION_IN_PROCESS 0x8000UL
|
||||||
|
|
||||||
#define FLAG_DISABLED 0x10000UL
|
#define FLAG_DISABLED 0x10000UL
|
||||||
#define FLAG_DISABLED_ALL 0x20000UL
|
#define FLAG_FREEZED 0x20000UL
|
||||||
#define FLAG_HALTED 0x40000UL
|
#define FLAG_HALTED 0x40000UL
|
||||||
#define FLAG_XON 0x80000UL
|
#define FLAG_XON 0x80000UL
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ e-mail anklimov@gmail.com
|
|||||||
Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_BSD);
|
Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_BSD);
|
||||||
static char syslogDeviceHostname[16];
|
static char syslogDeviceHostname[16];
|
||||||
|
|
||||||
#if defined(debugSerialPort)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog);
|
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog);
|
||||||
Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED);
|
Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED);
|
||||||
Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog);
|
Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog);
|
||||||
#else
|
#else
|
||||||
@@ -50,7 +50,7 @@ static char syslogDeviceHostname[16];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#if defined(debugSerialPort)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG);
|
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG);
|
||||||
Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED);
|
Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED);
|
||||||
Streamlog infoSerial (&debugSerialPort,LOG_INFO);
|
Streamlog infoSerial (&debugSerialPort,LOG_INFO);
|
||||||
@@ -139,6 +139,7 @@ bool owReady = false;
|
|||||||
bool configOk = false; // At least once connected to MQTT
|
bool configOk = false; // At least once connected to MQTT
|
||||||
bool configLoaded = false;
|
bool configLoaded = false;
|
||||||
bool initializedListeners = false;
|
bool initializedListeners = false;
|
||||||
|
uint8_t DHCP_failures = 0;
|
||||||
volatile int8_t ethernetIdleCount =0;
|
volatile int8_t ethernetIdleCount =0;
|
||||||
volatile int8_t configLocked = 0;
|
volatile int8_t configLocked = 0;
|
||||||
|
|
||||||
@@ -762,7 +763,8 @@ lan_status lanLoop() {
|
|||||||
wdt_dis();
|
wdt_dis();
|
||||||
if (lanStatus >= HAVE_IP_ADDRESS)
|
if (lanStatus >= HAVE_IP_ADDRESS)
|
||||||
{
|
{
|
||||||
int etherStatus = Ethernet.maintain();
|
int etherStatus = 0;
|
||||||
|
if (!DHCP_failures) etherStatus = Ethernet.maintain();
|
||||||
|
|
||||||
#ifndef Wiz5500
|
#ifndef Wiz5500
|
||||||
#define NO_LINK 5
|
#define NO_LINK 5
|
||||||
@@ -1108,7 +1110,11 @@ if (WiFi.status() == WL_CONNECTED) {
|
|||||||
IPAddress ip, dns, gw, mask;
|
IPAddress ip, dns, gw, mask;
|
||||||
int res = 1;
|
int res = 1;
|
||||||
infoSerial<<F("Starting lan")<<endl;
|
infoSerial<<F("Starting lan")<<endl;
|
||||||
if (sysConf.getIP(ip)) {
|
bool loadAddressRes = sysConf.getIP(ip);
|
||||||
|
if ( loadAddressRes &&
|
||||||
|
(!sysConf.getDHCPfallback() || (DHCP_failures >= DHCP_ATTEMPTS_FALLBACK))
|
||||||
|
)
|
||||||
|
{
|
||||||
infoSerial<<F("Loaded from flash IP:");
|
infoSerial<<F("Loaded from flash IP:");
|
||||||
printIPAddress(ip);
|
printIPAddress(ip);
|
||||||
if (sysConf.getDNS(dns)) {
|
if (sysConf.getDNS(dns)) {
|
||||||
@@ -1142,6 +1148,7 @@ if (WiFi.status() == WL_CONNECTED) {
|
|||||||
|
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
errorSerial<<F("Failed to configure Ethernet using DHCP. You can set ip manually!")<<F("'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n");
|
errorSerial<<F("Failed to configure Ethernet using DHCP. You can set ip manually!")<<F("'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n");
|
||||||
|
DHCP_failures++;
|
||||||
lanStatus = DO_REINIT;//-10;
|
lanStatus = DO_REINIT;//-10;
|
||||||
//timerLanCheckTime = millis();// + DHCP_RETRY_INTERVAL;
|
//timerLanCheckTime = millis();// + DHCP_RETRY_INTERVAL;
|
||||||
#ifdef RESET_PIN
|
#ifdef RESET_PIN
|
||||||
@@ -1149,8 +1156,25 @@ if (WiFi.status() == WL_CONNECTED) {
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
infoSerial<<F("Got IP address:");
|
infoSerial<<F("Got IP address:");
|
||||||
printIPAddress(Ethernet.localIP());
|
ip=Ethernet.localIP();
|
||||||
|
printIPAddress(ip);
|
||||||
|
|
||||||
infoSerial<<endl;
|
infoSerial<<endl;
|
||||||
|
|
||||||
|
sysConf.setIP(ip);
|
||||||
|
|
||||||
|
dns=Ethernet.dnsServerIP();
|
||||||
|
sysConf.setDNS(dns);
|
||||||
|
|
||||||
|
gw=Ethernet.gatewayIP();
|
||||||
|
sysConf.setGW(gw);
|
||||||
|
|
||||||
|
mask=Ethernet.subnetMask();
|
||||||
|
sysConf.setMask(mask);
|
||||||
|
|
||||||
|
sysConf.setDHCPfallback(true);
|
||||||
|
|
||||||
|
DHCP_failures = 0;
|
||||||
lanStatus = HAVE_IP_ADDRESS;
|
lanStatus = HAVE_IP_ADDRESS;
|
||||||
}
|
}
|
||||||
}//DHCP
|
}//DHCP
|
||||||
@@ -1608,6 +1632,7 @@ int cmdFunctionIp(int arg_cnt, char **args)
|
|||||||
printIPAddress(current_mask); */
|
printIPAddress(current_mask); */
|
||||||
//}
|
//}
|
||||||
infoSerial<<F("Saved\n");
|
infoSerial<<F("Saved\n");
|
||||||
|
sysConf.setDHCPfallback(false);
|
||||||
return 200;
|
return 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,7 +1782,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
|||||||
// FILE is the return STREAM type of the HTTPClient
|
// FILE is the return STREAM type of the HTTPClient
|
||||||
configStream = hclient.getURI(URI,NULL,get_header);
|
configStream = hclient.getURI(URI,NULL,get_header);
|
||||||
responseStatusCode = hclient.getLastReturnCode();
|
responseStatusCode = hclient.getLastReturnCode();
|
||||||
//debugSerial<<F("http retcode ")<<responseStatusCode<<endl;delay(100);
|
debugSerial<<F("http retcode ")<<responseStatusCode<<endl;delay(100);
|
||||||
//wdt_en();
|
//wdt_en();
|
||||||
|
|
||||||
if (configStream != NULL) {
|
if (configStream != NULL) {
|
||||||
@@ -2101,12 +2126,12 @@ void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
|||||||
void setup_main() {
|
void setup_main() {
|
||||||
|
|
||||||
#if (SERIAL_BAUD)
|
#if (SERIAL_BAUD)
|
||||||
#if defined(debugSerialPort)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
debugSerialPort.begin(SERIAL_BAUD);
|
debugSerialPort.begin(SERIAL_BAUD);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if not defined (__SAM3X8E__) && defined (debugSerialPort)
|
#if not defined (__SAM3X8E__) && defined (debugSerialPort) && !defined(NOSERIAL)
|
||||||
debugSerialPort.begin();
|
debugSerialPort.begin();
|
||||||
#endif
|
#endif
|
||||||
delay(1000);
|
delay(1000);
|
||||||
@@ -2125,13 +2150,13 @@ void setup_main() {
|
|||||||
if(SPIFFS.begin())
|
if(SPIFFS.begin())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if defined(debugSerialPort)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
debugSerialPort.println("SPIFFS Initialize....ok");
|
debugSerialPort.println("SPIFFS Initialize....ok");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(debugSerialPort)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
debugSerialPort.println("SPIFFS Initialization...failed");
|
debugSerialPort.println("SPIFFS Initialization...failed");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -2148,7 +2173,7 @@ void setup_main() {
|
|||||||
|
|
||||||
if (!sysConf.isValidSysConf())
|
if (!sysConf.isValidSysConf())
|
||||||
{
|
{
|
||||||
#if defined(debugSerialPort)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
debugSerialPort.println(F("No valid EEPROM data. Initializing."));
|
debugSerialPort.println(F("No valid EEPROM data. Initializing."));
|
||||||
#endif
|
#endif
|
||||||
sysConf.clear();
|
sysConf.clear();
|
||||||
@@ -2185,7 +2210,7 @@ void setup_main() {
|
|||||||
#else
|
#else
|
||||||
pinMode(TXEnablePin, OUTPUT);
|
pinMode(TXEnablePin, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
modbusSerial.begin(MODBUS_SERIAL_BAUD,dimPar);
|
modbusSerial.begin(MODBUS_SERIAL_BAUD,MODBUS_SERIAL_PARAM);
|
||||||
node.idle(&modbusIdle);
|
node.idle(&modbusIdle);
|
||||||
node.preTransmission(preTransmission);
|
node.preTransmission(preTransmission);
|
||||||
node.postTransmission(postTransmission);
|
node.postTransmission(postTransmission);
|
||||||
@@ -2277,11 +2302,17 @@ infoSerial<<F("\nFirmware MAC Address " QUOTE(CUSTOM_FIRMWARE_MAC));
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _modbus
|
#ifdef _modbus
|
||||||
infoSerial<<F("\n(+)MODBUS " QUOTE(MODBUS_DIMMER_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_SERIAL_BAUD));
|
infoSerial<<F("\n(+)MODBUS " QUOTE(MODBUS_SERIAL_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_SERIAL_BAUD));
|
||||||
#else
|
#else
|
||||||
infoSerial<<F("\n(-)MODBUS");
|
infoSerial<<F("\n(-)MODBUS");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef IPMODBUS
|
||||||
|
infoSerial<<F("\n(+)IPMODBUS ");// QUOTE(MODBUS_TCP_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_TCP_BAUD));
|
||||||
|
#else
|
||||||
|
infoSerial<<F("\n(-)IPMODBUS");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef OWIRE_DISABLE
|
#ifndef OWIRE_DISABLE
|
||||||
infoSerial<<F("\n(+)OWIRE");
|
infoSerial<<F("\n(+)OWIRE");
|
||||||
#ifdef USE_1W_PIN
|
#ifdef USE_1W_PIN
|
||||||
@@ -2400,13 +2431,17 @@ infoSerial<<F("\n(-)MULTIVENT");
|
|||||||
infoSerial<<F("\n(+)HUMIDIFIER");
|
infoSerial<<F("\n(+)HUMIDIFIER");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NOSERIAL
|
||||||
|
infoSerial<<F("\nNOSERIAL");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ELEVATOR_ENABLE
|
#ifdef ELEVATOR_ENABLE
|
||||||
infoSerial<<F("\n(+)ELEVATOR");
|
infoSerial<<F("\n(+)ELEVATOR");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IPMODBUS
|
//#ifdef IPMODBUS
|
||||||
infoSerial<<F("\n(+)IPMODBUS");
|
//infoSerial<<F("\n(+)IPMODBUS");
|
||||||
#endif
|
//#endif
|
||||||
infoSerial<<endl;
|
infoSerial<<endl;
|
||||||
|
|
||||||
// WDT_Disable( WDT ) ;
|
// WDT_Disable( WDT ) ;
|
||||||
@@ -2432,18 +2467,23 @@ void publishStat(){
|
|||||||
uint32_t ut = millis()/1000UL;
|
uint32_t ut = millis()/1000UL;
|
||||||
if (!mqttClient.connected() || ethernetIdleCount) return;
|
if (!mqttClient.connected() || ethernetIdleCount) return;
|
||||||
setTopic(topic,sizeof(topic),T_DEV);
|
setTopic(topic,sizeof(topic),T_DEV);
|
||||||
strncat_P(topic, stats_P, sizeof(topic));
|
strncat_P(topic, stats_P, sizeof(topic)-1);
|
||||||
strncat(topic, "/", sizeof(topic));
|
strncat(topic, "/", sizeof(topic));
|
||||||
strncat_P(topic, freeheap_P, sizeof(topic));
|
strncat_P(topic, freeheap_P, sizeof(topic)-1);
|
||||||
printUlongValueToStr(intbuf, fr);
|
printUlongValueToStr(intbuf, fr);
|
||||||
mqttClient.publish(topic,intbuf,true);
|
mqttClient.publish(topic,intbuf,true);
|
||||||
|
|
||||||
setTopic(topic,sizeof(topic),T_DEV);
|
setTopic(topic,sizeof(topic),T_DEV);
|
||||||
strncat_P(topic, stats_P, sizeof(topic));
|
strncat_P(topic, stats_P, sizeof(topic)-1);
|
||||||
strncat(topic, "/", sizeof(topic));
|
strncat(topic, "/", sizeof(topic));
|
||||||
strncat_P(topic, uptime_P, sizeof(topic));
|
strncat_P(topic, uptime_P, sizeof(topic)-1);
|
||||||
printUlongValueToStr(intbuf, ut);
|
printUlongValueToStr(intbuf, ut);
|
||||||
mqttClient.publish(topic,intbuf,true);
|
mqttClient.publish(topic,intbuf,true);
|
||||||
|
|
||||||
|
setTopic(topic,sizeof(topic),T_DEV);
|
||||||
|
strncat_P(topic, state_P, sizeof(topic)-1);
|
||||||
|
strncpy_P(intbuf, ready_P, sizeof(intbuf)-1);
|
||||||
|
mqttClient.publish(topic,intbuf,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupMacAddress() {
|
void setupMacAddress() {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#define INTERVAL_AC_POLLING 5000L
|
#define INTERVAL_AC_POLLING 5000L
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
//static int driverStatus = CST_UNKNOWN;
|
||||||
|
|
||||||
static int fresh =0;
|
static int fresh =0;
|
||||||
static int power = 0;
|
static int power = 0;
|
||||||
@@ -39,6 +39,32 @@ const char QUIET_P[] PROGMEM = "queit";
|
|||||||
const char SWING_P[] PROGMEM = "swing";
|
const char SWING_P[] PROGMEM = "swing";
|
||||||
const char RAW_P[] PROGMEM = "raw";
|
const char RAW_P[] PROGMEM = "raw";
|
||||||
|
|
||||||
|
void out_AC::getConfig(){
|
||||||
|
ACSerial=&AC_Serial;
|
||||||
|
if (item->getArgCount())
|
||||||
|
|
||||||
|
switch(portNum=item->getArg(0)){
|
||||||
|
case 0: ACSerial=&Serial;
|
||||||
|
|
||||||
|
break;
|
||||||
|
//#if defined (Serial1)
|
||||||
|
case 1: ACSerial=&Serial1;
|
||||||
|
break;
|
||||||
|
//#endif
|
||||||
|
//#if defined (Serial2)
|
||||||
|
case 2: ACSerial=&Serial2;
|
||||||
|
break;
|
||||||
|
//#endif
|
||||||
|
//#if defined (Serial3)
|
||||||
|
case 3: ACSerial=&Serial3;
|
||||||
|
break;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void out_AC::InsertData(byte data[], size_t size){
|
void out_AC::InsertData(byte data[], size_t size){
|
||||||
|
|
||||||
char s_mode[10];
|
char s_mode[10];
|
||||||
@@ -177,11 +203,11 @@ byte getCRC(byte req[], size_t size){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void out_AC::SendData(byte req[], size_t size){
|
void out_AC::SendData(byte req[], size_t size){
|
||||||
AC_Serial.write(req, size - 1);
|
ACSerial->write(req, size - 1);
|
||||||
AC_Serial.write(getCRC(req, size-1));
|
ACSerial->write(getCRC(req, size-1));
|
||||||
//AC_Serial.flush();
|
//ACSerial->flush();
|
||||||
item->setExt(millisNZ());
|
item->setExt(millisNZ());
|
||||||
debugSerial.print("AirCon<<");
|
debugSerial<<F("AirCon ")<<portNum<<F(" <<");
|
||||||
for (int i=0; i < size-1; i++)
|
for (int i=0; i < size-1; i++)
|
||||||
{
|
{
|
||||||
if (req[i] < 10){
|
if (req[i] < 10){
|
||||||
@@ -206,23 +232,30 @@ inline unsigned char toHex( char ch ){
|
|||||||
int out_AC::Setup()
|
int out_AC::Setup()
|
||||||
{
|
{
|
||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
debugSerial<<F("AC Init")<<endl;
|
if (!item) return 0;
|
||||||
AC_Serial.begin(9600);
|
debugSerial<<F("AC Init: ")<<portNum<<endl;
|
||||||
driverStatus = CST_INITIALIZED;
|
if (!portNum)// && (g_APinDescription[0].ulPinType == PIO_PA8A_URXD))
|
||||||
|
{
|
||||||
|
pinMode(0, INPUT_PULLUP);
|
||||||
|
}
|
||||||
|
ACSerial->begin(9600);
|
||||||
|
item->itemArr->subtype = CST_INITIALIZED;
|
||||||
|
//driverStatus = CST_INITIALIZED;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_AC::Stop()
|
int out_AC::Stop()
|
||||||
{
|
{
|
||||||
debugSerial<<F("AC De-Init")<<endl;
|
if (!item) return 0;
|
||||||
|
debugSerial<<F("AC De-Init: ")<<portNum<<endl;
|
||||||
driverStatus = CST_UNKNOWN;
|
item->itemArr->subtype = CST_UNKNOWN;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_AC::Status()
|
int out_AC::Status()
|
||||||
{
|
{
|
||||||
return driverStatus;
|
if (!item) return 0;
|
||||||
|
return item->itemArr->subtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_AC::isActive()
|
int out_AC::isActive()
|
||||||
@@ -240,16 +273,34 @@ if (cause!=POLLING_SLOW) return false;
|
|||||||
SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера
|
SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера
|
||||||
}
|
}
|
||||||
|
|
||||||
if(AC_Serial.available() >= 37){ //was 0
|
if(ACSerial->available() >= 37){ //was 0
|
||||||
AC_Serial.readBytes(data, 37);
|
ACSerial->readBytes(data, 37);
|
||||||
while(AC_Serial.available()){
|
while(ACSerial->available()){
|
||||||
delay(2);
|
delay(2);
|
||||||
AC_Serial.read();
|
ACSerial->read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugSerial<<F("AirCon ")<<portNum<<F(" >> ");
|
||||||
|
for (int i=0; i < 37-1; i++)
|
||||||
|
{
|
||||||
|
if (data[i] < 10){
|
||||||
|
debugSerial.print("0");
|
||||||
|
debugSerial.print(data[i], HEX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugSerial.print(data[i], HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (data[36] != inCheck){
|
if (data[36] != inCheck){
|
||||||
inCheck = data[36];
|
inCheck = data[36];
|
||||||
InsertData(data, 37);
|
InsertData(data, 37);
|
||||||
|
debugSerial<<F(" OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugSerial.println();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -434,8 +485,8 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
|||||||
hexbyte[0] = buf[i] ;
|
hexbyte[0] = buf[i] ;
|
||||||
hexbyte[1] = buf[i+1] ;
|
hexbyte[1] = buf[i+1] ;
|
||||||
data[i/2] = (toHex(hexbyte[0]) << 4) | toHex(hexbyte[1]);
|
data[i/2] = (toHex(hexbyte[0]) << 4) | toHex(hexbyte[1]);
|
||||||
AC_Serial.write(data, 37);
|
ACSerial->write(data, 37);
|
||||||
AC_Serial.flush();
|
ACSerial->flush();
|
||||||
publishTopic("RAW", buf);
|
publishTopic("RAW", buf);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@@ -474,12 +525,12 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
|||||||
data[9] = 1;
|
data[9] = 1;
|
||||||
data[10] = 77;
|
data[10] = 77;
|
||||||
data[11] = 95;
|
data[11] = 95;
|
||||||
AC_Serial.flush();
|
ACSerial->flush();
|
||||||
uint32_t ts=item->getExt();
|
uint32_t ts=item->getExt();
|
||||||
while (ts && !isTimeOver(ts,millis(),100)) yield();
|
while (ts && !isTimeOver(ts,millis(),100)) yield();
|
||||||
SendData(data, sizeof(data)/sizeof(byte));
|
SendData(data, sizeof(data)/sizeof(byte));
|
||||||
//InsertData(data, sizeof(data)/sizeof(byte));
|
//InsertData(data, sizeof(data)/sizeof(byte));
|
||||||
//AC_Serial.flush();
|
//ACSerial->flush();
|
||||||
//item->setExt(millisNZ());
|
//item->setExt(millisNZ());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ extern void modbusIdle(void) ;
|
|||||||
class out_AC : public abstractOut {
|
class out_AC : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_AC(Item * _item):abstractOut(_item){};
|
out_AC(Item * _item):abstractOut(_item){getConfig();};
|
||||||
|
void getConfig();
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
@@ -33,9 +34,16 @@ public:
|
|||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InsertData(byte data[], size_t size);
|
void InsertData(byte data[], size_t size);
|
||||||
void SendData(byte req[], size_t size);
|
void SendData(byte req[], size_t size);
|
||||||
|
uint8_t portNum;
|
||||||
|
#if defined (__SAM3X8E__)
|
||||||
|
UARTClass *ACSerial;
|
||||||
|
#else
|
||||||
|
HardwareSerial *ACSerial;
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -358,8 +358,10 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,paramObj->name);
|
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,paramObj->name);
|
||||||
if (execObj)
|
if (execObj)
|
||||||
{
|
{
|
||||||
|
aJsonObject * markObj = execObj;
|
||||||
|
if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||||
//Retrive previous data
|
//Retrive previous data
|
||||||
aJsonObject *lastMeasured = aJson.getObjectItem(execObj,"@S");
|
aJsonObject *lastMeasured = aJson.getObjectItem(markObj,"@S");
|
||||||
if (lastMeasured)
|
if (lastMeasured)
|
||||||
{
|
{
|
||||||
if (lastMeasured->type == aJson_Int)
|
if (lastMeasured->type == aJson_Int)
|
||||||
@@ -372,7 +374,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
else //No container to store value yet
|
else //No container to store value yet
|
||||||
{
|
{
|
||||||
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
||||||
aJson.addNumberToObject(execObj, "@S", (long) param);
|
aJson.addNumberToObject(markObj, "@S", (long) param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -386,7 +388,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
if (*submitParam)
|
if (*submitParam)
|
||||||
{
|
{
|
||||||
// Compare with last submitted val (if @V NOT marked as NULL in config)
|
// Compare with last submitted val (if @V NOT marked as NULL in config)
|
||||||
aJsonObject *settedValue = aJson.getObjectItem(execObj,"@V");
|
aJsonObject *settedValue = aJson.getObjectItem(markObj,"@V");
|
||||||
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
|
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
|
||||||
{
|
{
|
||||||
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
||||||
@@ -473,11 +475,14 @@ void out_Modbus::initLine()
|
|||||||
|
|
||||||
int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
||||||
{
|
{
|
||||||
if (!store) return -1;
|
if (!store) {errorSerial<<F(" internal send error - no store")<<endl; return -1;}
|
||||||
|
|
||||||
aJsonObject * templateParamObj = aJson.getObjectItem(store->parameters, paramName);
|
aJsonObject * templateParamObj = aJson.getObjectItem(store->parameters, paramName);
|
||||||
if (!templateParamObj) return -1;
|
if (!templateParamObj) {errorSerial<<F(" internal send error - no template")<<endl; return -1;}
|
||||||
|
|
||||||
aJsonObject * regObj = aJson.getObjectItem(templateParamObj, "reg");
|
aJsonObject * regObj = aJson.getObjectItem(templateParamObj, "reg");
|
||||||
if (!regObj) return -2;
|
if (!regObj) {errorSerial<<F(" internal send error - no regObj")<<endl; return -2;}
|
||||||
|
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
// int8_t regType = PAR_I16;
|
// int8_t regType = PAR_I16;
|
||||||
@@ -525,11 +530,16 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
|||||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
{
|
{
|
||||||
aJsonObject *execObj = itemParametersObj->child;
|
aJsonObject *execObj = itemParametersObj->child;
|
||||||
while (execObj && execObj->type == aJson_Object)
|
while (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array) )
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((execObj->subtype & MB_NEED_SEND) && !(execObj->subtype & MB_SEND_ERROR))
|
if ((execObj->subtype & MB_NEED_SEND) && !(execObj->subtype & MB_SEND_ERROR))
|
||||||
{
|
{
|
||||||
aJsonObject *outValue = aJson.getObjectItem(execObj,"@V");
|
|
||||||
|
aJsonObject * markObj = execObj;
|
||||||
|
if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||||
|
|
||||||
|
aJsonObject *outValue = aJson.getObjectItem(markObj,"@V");
|
||||||
if (outValue)
|
if (outValue)
|
||||||
{
|
{
|
||||||
modbusBusy=1;
|
modbusBusy=1;
|
||||||
@@ -571,7 +581,7 @@ if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenc
|
|||||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
{
|
{
|
||||||
aJsonObject *execObj = itemParametersObj->child;
|
aJsonObject *execObj = itemParametersObj->child;
|
||||||
while (execObj && execObj->type == aJson_Object)
|
while (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array))
|
||||||
{
|
{
|
||||||
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
||||||
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS)
|
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS)
|
||||||
@@ -667,7 +677,7 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
|||||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
{
|
{
|
||||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
||||||
if (execObj && execObj->type == aJson_Object)
|
if (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
||||||
@@ -680,7 +690,10 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
|||||||
{ //Schedule update
|
{ //Schedule update
|
||||||
execObj->subtype |= MB_NEED_SEND;
|
execObj->subtype |= MB_NEED_SEND;
|
||||||
|
|
||||||
aJsonObject *outValue = aJson.getObjectItem(execObj,"@V");
|
aJsonObject * markObj = execObj;
|
||||||
|
if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||||
|
|
||||||
|
aJsonObject *outValue = aJson.getObjectItem(markObj,"@V");
|
||||||
if (outValue) // Existant. Preserve original @type
|
if (outValue) // Existant. Preserve original @type
|
||||||
{
|
{
|
||||||
outValue->valueint=Value;
|
outValue->valueint=Value;
|
||||||
@@ -690,12 +703,12 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
|||||||
// If no @V in config - creating with INT type - normal behavior - no supress in-to-out
|
// If no @V in config - creating with INT type - normal behavior - no supress in-to-out
|
||||||
{
|
{
|
||||||
debugSerial<<F("Add @V: ")<<execObj->name<<endl;
|
debugSerial<<F("Add @V: ")<<execObj->name<<endl;
|
||||||
aJson.addNumberToObject(execObj, "@V", Value);
|
aJson.addNumberToObject(markObj, "@V", Value);
|
||||||
outValue = aJson.getObjectItem(execObj,"@V");
|
outValue = aJson.getObjectItem(markObj,"@V");
|
||||||
if (outValue) outValue->subtype =regType & 0xF;
|
if (outValue) outValue->subtype =regType & 0xF;
|
||||||
}
|
}
|
||||||
|
|
||||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
aJsonObject *polledValue = aJson.getObjectItem(markObj,"@S");
|
||||||
if (polledValue && outValue->type == aJson_Int) polledValue->valueint=Value; //to pevent suppressing to change back to previously polled value if this occurs before next polling
|
if (polledValue && outValue->type == aJson_Int) polledValue->valueint=Value; //to pevent suppressing to change back to previously polled value if this occurs before next polling
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ int out_Motor::Setup()
|
|||||||
{
|
{
|
||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
getConfig();
|
getConfig();
|
||||||
debugSerial.println("Motor Init");
|
debugSerial.println("Motor: Init");
|
||||||
pinMode(pinUp,OUTPUT);
|
pinMode(pinUp,OUTPUT);
|
||||||
pinMode(pinDown,OUTPUT);
|
pinMode(pinDown,OUTPUT);
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ return 1;
|
|||||||
|
|
||||||
int out_Motor::Stop()
|
int out_Motor::Stop()
|
||||||
{
|
{
|
||||||
debugSerial.println("Motor De-Init");
|
debugSerial.println("Motor: De-Init");
|
||||||
digitalWrite(pinUp,INACTIVE);
|
digitalWrite(pinUp,INACTIVE);
|
||||||
digitalWrite(pinDown,INACTIVE);
|
digitalWrite(pinDown,INACTIVE);
|
||||||
|
|
||||||
@@ -145,13 +145,13 @@ if (curPos>255) curPos=255;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (motorOfftime && isTimeOver(motorOfftime,millis(),maxOnTime))
|
if (motorOfftime && isTimeOver(motorOfftime,millis(),maxOnTime))
|
||||||
{dif = 0; debugSerial<<F("Motor timeout")<<endl;}
|
{dif = 0; debugSerial<<F("Motor: timeout")<<endl;}
|
||||||
else if (curPos>=0)
|
else if (curPos>=0)
|
||||||
dif=targetPos-curPos;
|
dif=targetPos-curPos;
|
||||||
else
|
else
|
||||||
dif=targetPos-255/2; // Have No feedback
|
dif=targetPos-255/2; // Have No feedback
|
||||||
|
|
||||||
debugSerial<<F("In:")<<pinFeedback<<F(" Val:")<<fb<<F("/")<<curPos<<F("->")<<targetPos<<F(" delta:")<<dif<<endl;
|
debugSerial<<F("Motor: in:")<<pinFeedback<<F(" Val:")<<fb<<F("/")<<curPos<<F("->")<<targetPos<<F(" delta:")<<dif<<endl;
|
||||||
|
|
||||||
if (dif<-POS_ERR)
|
if (dif<-POS_ERR)
|
||||||
{
|
{
|
||||||
@@ -241,7 +241,7 @@ else
|
|||||||
|
|
||||||
}
|
}
|
||||||
else //Target zone
|
else //Target zone
|
||||||
{ debugSerial.println("Target");
|
{ debugSerial.println("Motor: Target");
|
||||||
digitalWrite(pinUp,INACTIVE);
|
digitalWrite(pinUp,INACTIVE);
|
||||||
digitalWrite(pinDown,INACTIVE);
|
digitalWrite(pinDown,INACTIVE);
|
||||||
item->setExt(0);
|
item->setExt(0);
|
||||||
@@ -263,10 +263,7 @@ int out_Motor::getChanType()
|
|||||||
|
|
||||||
int out_Motor::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
int out_Motor::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||||
{
|
{
|
||||||
//int chActive = item->isActive();
|
|
||||||
//bool toExecute = (chActive>0);
|
|
||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
//itemCmd st(ST_PERCENTS,CMD_VOID);
|
|
||||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||||
|
|
||||||
item->setFlag(FLAG_ACTION_NEEDED);
|
item->setFlag(FLAG_ACTION_NEEDED);
|
||||||
@@ -276,30 +273,15 @@ switch(suffixCode)
|
|||||||
case S_NOTFOUND:
|
case S_NOTFOUND:
|
||||||
// turn on and set
|
// turn on and set
|
||||||
toExecute = true;
|
toExecute = true;
|
||||||
debugSerial<<F("Forced execution");
|
debugSerial<<F("Motor: Forced execution");
|
||||||
case S_SET:
|
case S_SET:
|
||||||
//case S_ESET:
|
//case S_ESET:
|
||||||
if (!cmd.isValue()) return 0;
|
if (!cmd.isValue()) return 0;
|
||||||
// item->setVal(cmd.getPercents());
|
|
||||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
||||||
/*
|
|
||||||
st.assignFrom(cmd);
|
|
||||||
//Store
|
|
||||||
st.saveItem(item);
|
|
||||||
if (!suffixCode)
|
|
||||||
{
|
|
||||||
if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF);
|
|
||||||
if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON);
|
|
||||||
item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
|
||||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
|
||||||
}
|
|
||||||
else item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
|
||||||
*/
|
|
||||||
return 1;
|
return 1;
|
||||||
//break;
|
//break;
|
||||||
|
|
||||||
case S_CMD:
|
case S_CMD:
|
||||||
//item->setCmd(cmd.getCmd());
|
|
||||||
switch (cmd.getCmd())
|
switch (cmd.getCmd())
|
||||||
{
|
{
|
||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
@@ -307,7 +289,6 @@ case S_CMD:
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case CMD_OFF:
|
case CMD_OFF:
|
||||||
////item->SendStatus(FLAG_COMMAND);
|
|
||||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ int out_Multivent::getChanType()
|
|||||||
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||||
|
|
||||||
@@ -229,6 +230,9 @@ debugSerial << F("Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")
|
|||||||
|
|
||||||
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
|
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
|
||||||
|
|
||||||
|
//Move gates only if fan is actually on
|
||||||
|
if (!fanV) return 1;
|
||||||
|
|
||||||
i=NULL;
|
i=NULL;
|
||||||
if (gatesObj) i = gatesObj->child; //Pass 2: re-distribute airflow
|
if (gatesObj) i = gatesObj->child; //Pass 2: re-distribute airflow
|
||||||
|
|
||||||
@@ -250,11 +254,11 @@ while (i)
|
|||||||
debugSerial<<i->name<<(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
|
debugSerial<<i->name<<(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// executeCommand(i,-1,itemCmd().Percents255(out));
|
|
||||||
if (out != outObj->valueint)
|
if ((out != outObj->valueint))
|
||||||
{
|
{
|
||||||
//report out
|
//report out
|
||||||
executeCommand(i,-1,itemCmd().Percents255(out));
|
executeCommand(i,-1,itemCmd().Percents255(out));
|
||||||
outObj->valueint=out;
|
outObj->valueint=out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,37 +266,6 @@ while (i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
switch(suffixCode)
|
|
||||||
{
|
|
||||||
case S_NOTFOUND:
|
|
||||||
// turn on and set
|
|
||||||
toExecute = true;
|
|
||||||
debugSerial<<F("Forced execution");
|
|
||||||
case S_SET:
|
|
||||||
if (!cmd.isValue()) return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
//break;
|
|
||||||
|
|
||||||
case S_CMD:
|
|
||||||
//item->setCmd(cmd.getCmd());
|
|
||||||
switch (cmd.getCmd())
|
|
||||||
{
|
|
||||||
case CMD_ON:
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case CMD_OFF:
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
} //switch cmd
|
|
||||||
|
|
||||||
break;
|
|
||||||
} //switch suffix
|
|
||||||
debugSerial<<F("Unknown cmd")<<endl;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ bool out_pid::getConfig()
|
|||||||
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
||||||
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
||||||
{
|
{
|
||||||
errorSerial<<F("Invalid PID param array.")<<endl;
|
errorSerial<<F("PID: Invalid param array.")<<endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
double outMin=0.;
|
double outMin=0.;
|
||||||
@@ -103,7 +103,7 @@ bool out_pid::getConfig()
|
|||||||
if (limits) store->pid->SetOutputLimits(outMin,outMax);
|
if (limits) store->pid->SetOutputLimits(outMin,outMax);
|
||||||
store->pid->SetSampleTime(dT*1000.0);
|
store->pid->SetSampleTime(dT*1000.0);
|
||||||
return true;}
|
return true;}
|
||||||
else errorSerial<<F("PID already initialized")<<endl;
|
else errorSerial<<F("PID: already initialized")<<endl;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ store->pid=NULL;
|
|||||||
//store->timestamp=millis();
|
//store->timestamp=millis();
|
||||||
if (getConfig())
|
if (getConfig())
|
||||||
{
|
{
|
||||||
infoSerial<<F("PID config loaded ")<< item->itemArr->name<<endl;
|
infoSerial<<F("PID: config loaded ")<< item->itemArr->name<<endl;
|
||||||
//item->On(); // Turn ON pid by default
|
//item->On(); // Turn ON pid by default
|
||||||
// if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
// if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||||
// if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
// if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||||
@@ -129,7 +129,7 @@ if (getConfig())
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ errorSerial<<F("PID config error")<<endl;
|
{ errorSerial<<F("PID: config error")<<endl;
|
||||||
store->driverStatus = CST_FAILED;
|
store->driverStatus = CST_FAILED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ else
|
|||||||
|
|
||||||
int out_pid::Stop()
|
int out_pid::Stop()
|
||||||
{
|
{
|
||||||
debugSerial.println("PID De-Init");
|
debugSerial.println("PID: De-Init");
|
||||||
if (store) delete (store->pid);
|
if (store) delete (store->pid);
|
||||||
delete store;
|
delete store;
|
||||||
item->setPersistent(NULL);
|
item->setPersistent(NULL);
|
||||||
@@ -163,30 +163,33 @@ int out_pid::Poll(short cause)
|
|||||||
{
|
{
|
||||||
if (cause==POLLING_SLOW) return 0;
|
if (cause==POLLING_SLOW) return 0;
|
||||||
if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCmd()!=CMD_OFF))
|
if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCmd()!=CMD_OFF))
|
||||||
{
|
{
|
||||||
//double prevOut=store->output;
|
if (item->getCmd() != CMD_OFF && ! item->getFlag(FLAG_DISABLED))
|
||||||
//itemCmd st;
|
|
||||||
//st.loadItem(item);
|
|
||||||
//short cmd = st.getCmd();
|
|
||||||
if (item->getCmd() != CMD_OFF && /* item->getCmd() != CMD_DISABLE*/ ! item->getFlag(FLAG_DISABLED))
|
|
||||||
{
|
{
|
||||||
if(store->pid->Compute() )
|
if(store->pid->Compute() )
|
||||||
{
|
{
|
||||||
float alarmVal;
|
float alarmVal;
|
||||||
if (store->alarmArmed && ((alarmVal=getAlarmVal())>=0.)) store->output=alarmVal;
|
if (store->alarmArmed && ((alarmVal=getAlarmVal())>=0.)) store->output=alarmVal;
|
||||||
debugSerial<<F("PID ")<<item->itemArr->name<<F(" set:")<<store->setpoint<<F(" in:")<<store->input<<(" out:") << store->output <<F(" P:")<<store->pid->GetKp() <<F(" I:")<<store->pid->GetKi() <<F(" D:")<<store->pid->GetKd();
|
|
||||||
if (store->alarmArmed) debugSerial << F(" Alarm");
|
debugSerial<<F("PID: ")<<item->itemArr->name<<F(" set:")<<store->setpoint<<F(" in:")<<store->input<<(" out:") << store->output <<F(" P:")<<store->pid->GetKp() <<F(" I:")<<store->pid->GetKi() <<F(" D:")<<store->pid->GetKd();
|
||||||
|
//if (item->getFlag(FLAG_DISABLED)) debugSerial << F(" <DIS>");
|
||||||
|
if (store->alarmArmed) debugSerial << F(" <ALM>");
|
||||||
debugSerial<<endl;
|
debugSerial<<endl;
|
||||||
|
|
||||||
if (((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) || (item->getCmd() == CMD_ENABLE)) && !store->alarmArmed)
|
if (((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) || (item->getFlag(FLAG_ACTION_NEEDED))) && !store->alarmArmed)
|
||||||
{
|
{
|
||||||
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
||||||
if ((item->getCmd() == CMD_ENABLE) && (store->output>0.))
|
|
||||||
|
if (((store->prevOut == 0.) && (store->output>0)) || item->getFlag(FLAG_ACTION_NEEDED))
|
||||||
|
// if ((item->getFlag(FLAG_ACTION_NEEDED)) && (store->output>0.))
|
||||||
{
|
{
|
||||||
executeCommand(oCmd,-1,itemCmd().Cmd(CMD_ON));
|
executeCommand(oCmd,-1,itemCmd().Cmd(CMD_ON));
|
||||||
item->setCmd(CMD_VOID);
|
// item->clearFlag(FLAG_ACTION_NEEDED);
|
||||||
}
|
}
|
||||||
itemCmd value((float) (store->output));// * (100./255.)));
|
|
||||||
|
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||||
|
|
||||||
|
itemCmd value((float) (store->output));
|
||||||
value.setSuffix(S_SET);
|
value.setSuffix(S_SET);
|
||||||
executeCommand(oCmd,-1,value);
|
executeCommand(oCmd,-1,value);
|
||||||
store->prevOut=store->output;
|
store->prevOut=store->output;
|
||||||
@@ -198,7 +201,8 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm
|
|||||||
alarm(true);
|
alarm(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 1;//store->pollingInterval;
|
return 1;//store->pollingInterval;
|
||||||
};
|
};
|
||||||
@@ -208,7 +212,7 @@ float out_pid::getAlarmVal()
|
|||||||
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
||||||
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
||||||
{
|
{
|
||||||
errorSerial<<F("Invalid PID param array.")<<endl;
|
errorSerial<<F("PID: Invalid param array.")<<endl;
|
||||||
return -1.;
|
return -1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +248,7 @@ float out_pid::getAlarmVal()
|
|||||||
else if (!alarmValDefined) outAlarm = 255.;
|
else if (!alarmValDefined) outAlarm = 255.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugSerial<<F("Alarm value: ")<<outAlarm<< " ";
|
// debugSerial<<F("Alarm value: ")<<outAlarm<< " ";
|
||||||
return outAlarm;
|
return outAlarm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +299,7 @@ case S_VAL:
|
|||||||
// Input value for PID
|
// Input value for PID
|
||||||
if (!cmd.isValue()) return 0;
|
if (!cmd.isValue()) return 0;
|
||||||
store->input=cmd.getFloat();
|
store->input=cmd.getFloat();
|
||||||
debugSerial<<F("Input value:")<<store->input<<endl;
|
debugSerial<<F("PID: ")<< item->itemArr->name <<F(" Input value:")<<store->input<<endl;
|
||||||
|
|
||||||
store->alarmTimer=millis();
|
store->alarmTimer=millis();
|
||||||
if (store->alarmArmed)
|
if (store->alarmArmed)
|
||||||
@@ -309,11 +313,11 @@ return 1;
|
|||||||
|
|
||||||
case S_NOTFOUND:
|
case S_NOTFOUND:
|
||||||
case S_SET:
|
case S_SET:
|
||||||
//case S_ESET:
|
|
||||||
// Setpoint for PID
|
// Setpoint for PID
|
||||||
if (!cmd.isValue()) return 0;
|
if (!cmd.isValue()) return 0;
|
||||||
store->setpoint=cmd.getFloat();
|
store->setpoint=cmd.getFloat();
|
||||||
debugSerial<<F("Setpoint:")<<store->setpoint<<endl;
|
debugSerial<<F("PID: ")<< item->itemArr->name <<F(" Setpoint:")<<store->setpoint<<endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
aJsonObject * itemCascadeObj = aJson.getArrayItem(item->itemArg, 2);
|
aJsonObject * itemCascadeObj = aJson.getArrayItem(item->itemArg, 2);
|
||||||
@@ -345,11 +349,14 @@ case S_CTRL:
|
|||||||
case CMD_DRY:
|
case CMD_DRY:
|
||||||
|
|
||||||
executeCommand(oCmd,-1,value);
|
executeCommand(oCmd,-1,value);
|
||||||
|
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
|
||||||
|
item->SendStatus(FLAG_FLAGS);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case CMD_ENABLE:
|
case CMD_ENABLE:
|
||||||
//item->setCmd(CMD_ENABLE);
|
//item->setCmd(CMD_ENABLE);
|
||||||
//item->SendStatus(FLAG_COMMAND);
|
//item->SendStatus(FLAG_COMMAND);
|
||||||
|
item->setFlag(FLAG_ACTION_NEEDED);
|
||||||
executeCommand(oCmd,-1,value);
|
executeCommand(oCmd,-1,value);
|
||||||
store->prevOut=-2.0;
|
store->prevOut=-2.0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#define DHCP_ATTEMPTS_FALLBACK 3
|
||||||
#define TENS_FRACT_LEN 2
|
#define TENS_FRACT_LEN 2
|
||||||
#define TENS_BASE 100
|
#define TENS_BASE 100
|
||||||
|
|
||||||
@@ -138,12 +138,22 @@
|
|||||||
#define MODBUS_SERIAL_BAUD 9600
|
#define MODBUS_SERIAL_BAUD 9600
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MODBUS_DIMMER_PARAM
|
#ifndef MODBUS_SERIAL_PARAM
|
||||||
#define MODBUS_DIMMER_PARAM SERIAL_8N1
|
#define MODBUS_SERIAL_PARAM SERIAL_8N1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define dimPar MODBUS_DIMMER_PARAM
|
/*
|
||||||
#define fmPar SERIAL_8N1
|
#ifndef MODBUS_TCP_BAUD
|
||||||
|
#define MODBUS_TCP_BAUD 9600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MODBUS_TCP_PARAM
|
||||||
|
#define MODBUS_TCP_PARAM SERIAL_8N1
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MODBUS_FM_BAUD 9600
|
||||||
|
#define MODBUS_FM_PARAM SERIAL_8N1
|
||||||
|
|
||||||
#ifndef SERIAL_BAUD
|
#ifndef SERIAL_BAUD
|
||||||
#define SERIAL_BAUD 115200
|
#define SERIAL_BAUD 115200
|
||||||
@@ -303,7 +313,7 @@
|
|||||||
//#ifdef M5STACK
|
//#ifdef M5STACK
|
||||||
//#define debugSerial M5.Lcd
|
//#define debugSerial M5.Lcd
|
||||||
//#endif
|
//#endif
|
||||||
#ifdef noSerial
|
#ifdef NOSERIAL
|
||||||
#undef debugSerialPort
|
#undef debugSerialPort
|
||||||
#else
|
#else
|
||||||
#ifndef debugSerialPort
|
#ifndef debugSerialPort
|
||||||
@@ -346,3 +356,9 @@
|
|||||||
//#define PINS_COUNT NUM_DIGITAL_PINS
|
//#define PINS_COUNT NUM_DIGITAL_PINS
|
||||||
#define isAnalogPin(p) ((p >= 14) && (p<=21))
|
#define isAnalogPin(p) ((p >= 14) && (p<=21))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef AVR
|
||||||
|
#define minimalMemory 200
|
||||||
|
#else
|
||||||
|
#define minimalMemory 1200
|
||||||
|
#endif
|
||||||
@@ -30,7 +30,7 @@ Streamlog::Streamlog (SerialPortType * _serialPort, uint8_t _severity, uint8_t
|
|||||||
severity=_severity;
|
severity=_severity;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
void Streamlog::begin(unsigned long speed)
|
void Streamlog::begin(unsigned long speed)
|
||||||
{
|
{
|
||||||
if (serialPort) serialPort->begin(speed);
|
if (serialPort) serialPort->begin(speed);
|
||||||
@@ -40,6 +40,7 @@ void Streamlog::end()
|
|||||||
{
|
{
|
||||||
if (serialPort) serialPort->end();
|
if (serialPort) serialPort->end();
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
int Streamlog::available(void)
|
int Streamlog::available(void)
|
||||||
{
|
{
|
||||||
@@ -79,7 +80,7 @@ if (syslogInitialized && (udpDebugLevel>=severity))
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (logBufferPos<LOGBUFFER_SIZE-1 && (ch!='\r')) logBuffer[logBufferPos++]=ch;
|
if ((logBufferPos<LOGBUFFER_SIZE-1) && (ch!='\r')) logBuffer[logBufferPos++]=ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -87,8 +88,8 @@ if (syslogInitialized && (udpDebugLevel>=severity))
|
|||||||
#if defined (STATUSLED)
|
#if defined (STATUSLED)
|
||||||
if ((ch=='\n') && ledPattern) statusLED.flash(ledPattern);
|
if ((ch=='\n') && ledPattern) statusLED.flash(ledPattern);
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(noSerial)
|
||||||
if (serialPort && (serialDebugLevel>=severity)) return serialPort->write(ch);
|
if (serialPort && (serialDebugLevel>=severity)) serialPort->write(ch);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class Streamlog : public Print
|
|||||||
#else
|
#else
|
||||||
Streamlog (SerialPortType * _serialPort, uint8_t _severity = LOG_DEBUG, uint8_t _ledPattern = 0);
|
Streamlog (SerialPortType * _serialPort, uint8_t _severity = LOG_DEBUG, uint8_t _ledPattern = 0);
|
||||||
#endif
|
#endif
|
||||||
void begin(unsigned long speed);
|
//void begin(unsigned long speed);
|
||||||
void end() ;
|
//void end() ;
|
||||||
|
|
||||||
int available(void);
|
int available(void);
|
||||||
int peek(void);
|
int peek(void);
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ const char EEPROM_signature[] = EEPROM_SIGNATURE;
|
|||||||
uint8_t notGetConfigFromHTTP:1;
|
uint8_t notGetConfigFromHTTP:1;
|
||||||
uint8_t udpDebugLevel:3;
|
uint8_t udpDebugLevel:3;
|
||||||
uint8_t notSaveSuccedConfig:1;
|
uint8_t notSaveSuccedConfig:1;
|
||||||
uint8_t spare2;
|
uint8_t dhcpFallback:1;
|
||||||
|
uint8_t spare2:7;
|
||||||
uint16_t sysConfigHash;
|
uint16_t sysConfigHash;
|
||||||
};
|
};
|
||||||
} systemConfigFlags;
|
} systemConfigFlags;
|
||||||
|
|||||||
@@ -114,7 +114,8 @@ const char LOW_P[] PROGMEM = "LOW";
|
|||||||
const char ERROR_P[] PROGMEM = "ERR";
|
const char ERROR_P[] PROGMEM = "ERR";
|
||||||
const char ENABLE_P[] PROGMEM = "ENABLE";
|
const char ENABLE_P[] PROGMEM = "ENABLE";
|
||||||
const char DISABLE_P[] PROGMEM = "DISABLE";
|
const char DISABLE_P[] PROGMEM = "DISABLE";
|
||||||
|
const char FREEZE_P[] PROGMEM = "FREEZE";
|
||||||
|
const char UNFREEZE_P[] PROGMEM = "UNFREEZE";
|
||||||
|
|
||||||
// SubTopics
|
// SubTopics
|
||||||
const char SET_P[] PROGMEM = "set";
|
const char SET_P[] PROGMEM = "set";
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ unsigned long freeRam() {
|
|||||||
extern char _end;
|
extern char _end;
|
||||||
extern "C" char *sbrk(int i);
|
extern "C" char *sbrk(int i);
|
||||||
|
|
||||||
unsigned long freeRam() {
|
unsigned long freeRam() {
|
||||||
char *ramstart = (char *) 0x20070000;
|
char *ramstart = (char *) 0x20070000;
|
||||||
char *ramend = (char *) 0x20088000;
|
char *ramend = (char *) 0x20088000;
|
||||||
char *heapend = sbrk(0);
|
char *heapend = sbrk(0);
|
||||||
@@ -719,6 +719,13 @@ switch (cmdType)
|
|||||||
Item it(item->valuestring);
|
Item it(item->valuestring);
|
||||||
if (it.isValid())
|
if (it.isValid())
|
||||||
{
|
{
|
||||||
|
int fr = freeRam();
|
||||||
|
if (fr < minimalMemory)
|
||||||
|
{
|
||||||
|
errorSerial<<F("CTRL/exec: OutOfMemory: ")<<fr<<endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (itemCommand) it.Ctrl(itemCommand);
|
if (itemCommand) it.Ctrl(itemCommand);
|
||||||
else it.Ctrl(_itemCmd);
|
else it.Ctrl(_itemCmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ void SetAddr(char * out, uint8_t* addr);
|
|||||||
uint8_t HEX2DEC(char i);
|
uint8_t HEX2DEC(char i);
|
||||||
int getInt(char ** chan);
|
int getInt(char ** chan);
|
||||||
itemCmd getNumber(char ** chan);
|
itemCmd getNumber(char ** chan);
|
||||||
unsigned long freeRam ();
|
unsigned long freeRam ();
|
||||||
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);
|
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);
|
||||||
int log(const char *str, ...);
|
int log(const char *str, ...);
|
||||||
void printFloatValueToStr(char *valstr, float value);
|
void printFloatValueToStr(char *valstr, float value);
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ monitor_speed = 115200
|
|||||||
platform = atmelavr
|
platform = atmelavr
|
||||||
board = megaatmega2560
|
board = megaatmega2560
|
||||||
upload_port = net:192.168.88.2:23000
|
upload_port = net:192.168.88.2:23000
|
||||||
|
_upload_command = custom-build-flags/upload_mega2560slim-5100 $SOURCE
|
||||||
framework = arduino
|
framework = arduino
|
||||||
build_flags = !python get_build_flags.py mega2560slim-5100
|
build_flags = !python get_build_flags.py mega2560slim-5100
|
||||||
extra_scripts = post:toBin.py
|
extra_scripts = post:toBin.py
|
||||||
|
|||||||
Reference in New Issue
Block a user