diff --git a/build-flags/build_flags_due b/build-flags/build_flags_due index e8b567f..c80ddab 100644 --- a/build-flags/build_flags_due +++ b/build-flags/build_flags_due @@ -1,7 +1,7 @@ #-DW5500_CS_PIN=53 -DDMX_SMOOTH -DSYSLOG_ENABLE -#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 +#-DMODBUS_SERIAL_PARAM=SERIAL_8E1 -DARTNET_ENABLE -DOTA -DSTATUSLED diff --git a/build-flags/build_flags_esp32-wifi b/build-flags/build_flags_esp32-wifi index 652d728..a7e3b84 100644 --- a/build-flags/build_flags_esp32-wifi +++ b/build-flags/build_flags_esp32-wifi @@ -26,6 +26,10 @@ #-DmodbusSerial=Serial1 #-DMODBUS_DEBUG +#-DMODBUS_UART_RX_PIN=16 +#-DMODBUS_UART_TX_PIN=17 +#-DmodbusSerial=Serial2 + # Use default pins for modbus UART #-DMODBUS_UART_RX_PIN=-1 #-DMODBUS_UART_TX_PIN=-1 diff --git a/build-flags/build_flags_lighthub21 b/build-flags/build_flags_lighthub21 index b888848..a21fefc 100644 --- a/build-flags/build_flags_lighthub21 +++ b/build-flags/build_flags_lighthub21 @@ -12,8 +12,8 @@ -DTIMER_INT #-DFLASH_OFFSET=-256 -# Serial parameters for LEGACY Modbus --DMODBUS_DIMMER_PARAM=SERIAL_8E1 +# default MODBUS Serial parameters for LEGACY Modbus and MODBUS over IP +#-DMODBUS_SERIAL_PARAM=SERIAL_8E1 #Set Logariphmic law for DMX channels bright -DBRIGHT_LOG diff --git a/build-flags/build_flags_mega2560-5100 b/build-flags/build_flags_mega2560-5100 index 3418a57..312f598 100644 --- a/build-flags/build_flags_mega2560-5100 +++ b/build-flags/build_flags_mega2560-5100 @@ -1,4 +1,4 @@ -#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 +#-DMODBUS_SERIAL_PARAM=SERIAL_8E1 -DAVR_DMXOUT_PIN=18 -DSYSLOG_ENABLE -DWiz5100 diff --git a/build-flags/build_flags_mega2560-5500 b/build-flags/build_flags_mega2560-5500 index b445e35..6927212 100644 --- a/build-flags/build_flags_mega2560-5500 +++ b/build-flags/build_flags_mega2560-5500 @@ -1,5 +1,5 @@ -DWiz5500 -#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 +#-DMODBUS_SERIAL_PARAM=SERIAL_8E1 -DAVR_DMXOUT_PIN=18 -DSYSLOG_ENABLE #-DPID_DISABLE diff --git a/build-flags/build_flags_mega2560-optiboot b/build-flags/build_flags_mega2560-optiboot index b248c5f..7f69bf2 100644 --- a/build-flags/build_flags_mega2560-optiboot +++ b/build-flags/build_flags_mega2560-optiboot @@ -1,5 +1,5 @@ -#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 +#-DMODBUS_SERIAL_PARAM=SERIAL_8E1 #-DAVR_DMXOUT_PIN=18 -DDMX_DISABLE -DMODBUS_DISABLE diff --git a/build-flags/build_flags_mega2560slim-5100 b/build-flags/build_flags_mega2560slim-5100 index 0ee7954..0fb2dac 100644 --- a/build-flags/build_flags_mega2560slim-5100 +++ b/build-flags/build_flags_mega2560slim-5100 @@ -1,9 +1,9 @@ -#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 +#-DMODBUS_SERIAL_PARAM=SERIAL_8E1 #-DAVR_DMXOUT_PIN=18 -DDMX_DISABLE -DMODBUS_DISABLE -#-DMBUS_DISABLE +-DMBUS_DISABLE #-DOWIRE_DISABLE -DDHT_DISABLE -DCOUNTER_DISABLE diff --git a/compiled/m5stack/StartCounter.ino.bin b/compiled/m5stack/StartCounter.ino.bin new file mode 100644 index 0000000..14732a0 Binary files /dev/null and b/compiled/m5stack/StartCounter.ino.bin differ diff --git a/lighthub/abstractout.cpp b/lighthub/abstractout.cpp index b8516ee..615f689 100644 --- a/lighthub/abstractout.cpp +++ b/lighthub/abstractout.cpp @@ -12,6 +12,8 @@ int abstractOut::isActive() case CMD_VOID: return 0; break; + case CMD_ON: //trying (PWM ON set=0 issue) + return 1; default: st.loadItem(item); return st.getPercents255(); diff --git a/lighthub/abstractout.h b/lighthub/abstractout.h index a717b7d..a87cd0a 100644 --- a/lighthub/abstractout.h +++ b/lighthub/abstractout.h @@ -10,6 +10,7 @@ public: abstractOut(Item * _item):abstractCh(){item=_item;}; virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) =0; virtual int isActive(); + virtual bool isAllowed(itemCmd cmd){return true;}; virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);}; virtual int getChanType(){return 0;} virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead diff --git a/lighthub/config.cpp b/lighthub/config.cpp index 259697f..53e7f27 100644 --- a/lighthub/config.cpp +++ b/lighthub/config.cpp @@ -293,6 +293,19 @@ bool systemConfig::setConfigFlags(systemConfigFlags 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() { systemConfigFlags flags = getConfigFlags(); diff --git a/lighthub/config.h b/lighthub/config.h index 7234b53..05a97f3 100644 --- a/lighthub/config.h +++ b/lighthub/config.h @@ -61,6 +61,9 @@ class systemConfig { bool saveETAG(); bool loadETAG(); + bool getDHCPfallback(); + bool setDHCPfallback(bool flag); + systemConfigFlags getConfigFlags(); bool setConfigFlags(systemConfigFlags flags); diff --git a/lighthub/ipmodbus.cpp b/lighthub/ipmodbus.cpp index 322b611..8984cfb 100644 --- a/lighthub/ipmodbus.cpp +++ b/lighthub/ipmodbus.cpp @@ -541,9 +541,9 @@ void setupIpmodbus(){ // Calculate Modbus RTU character timeout and frame delay byte bits = // number of bits per character (11 in default Modbus RTU settings) 1 + // start bit - (((MODBUS_DIMMER_PARAM & 0x06) >> 1) + 5) + // data bits - (((MODBUS_DIMMER_PARAM & 0x08) >> 3) + 1); // stop bits - if (((MODBUS_DIMMER_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present) + (((MODBUS_SERIAL_PARAM & 0x06) >> 1) + 5) + // data bits + (((MODBUS_SERIAL_PARAM & 0x08) >> 3) + 1); // stop bits + if (((MODBUS_SERIAL_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present) //bits = 11; int T = ((unsigned long)bits * 1000000UL) / MODBUS_SERIAL_BAUD; // time to send 1 character over serial in microseconds diff --git a/lighthub/item.cpp b/lighthub/item.cpp index bb05767..6d078c0 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -107,7 +107,7 @@ int txt2subItem(char *payload) { if (!payload || !strlen(payload)) return S_NOTFOUND; // Check for command 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, MODE_P) == 0) cmd = S_MODE; 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); if (itemCmd && (itemCmd->type == aJson_Int)) { - return itemCmd->valueint & flag & FLAG_MASK; + return (uint32_t) itemCmd->valueint & flag & FLAG_MASK; } return 0; } @@ -572,7 +572,12 @@ long int Item::limitSetValue() int Item::Ctrl(char * payload, char * subItem) { if (!payload) return 0; - +int fr = freeRam(); +if (fr < minimalMemory) + { + errorSerial<subtype > 0)) + { + return timestampObj->subtype; + } +return 0; +} - if (!suffixCode && subItem && strlen(subItem)) - { - suffixCode = retrieveCode(&subItem); - if (!cmd.getSuffix()) cmd.setSuffix(suffixCode); - } +int Item::scheduleOppositeCommand(itemCmd cmd) +{ + itemCmd nextCmd=cmd; + + 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<0); @@ -950,11 +1009,12 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion) { if (fr<350) { - errorSerial<type == aJson_Array && operation) { + chActive=(isActive()>0); digGroup(itemArg,&cmd,subItem); } res=1; @@ -965,7 +1025,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion) case CMD_RESTORE: // individual for group members switch (t = getCmd()) { 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.Cmd(CMD_ON); //turning on 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 switch (t = getCmd()) { 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 status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE; break; default: - debugSerial << F("XOFF skipped. Prev cmd:") << t <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 - { + { + + cmd.loadItemDef(this); cmd.Cmd(CMD_ON); command2Set=CMD_XON; @@ -999,13 +1070,21 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion) } else { - debugSerial<0); - if (chActive) //if channel was active before CMD_HALT + if (chActive == -1) chActive=(isActive()>0); + 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); command2Set=CMD_HALT; @@ -1013,7 +1092,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion) } else { - debugSerial<0); toExecute=chActive || toExecute; // Execute if active - debugSerial<Ctrl(cmd, subItem, toExecute); - if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE; - //if (res==-1) status2Send=0; ///////not working - } -else +if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED))) { -switch (itemType) { -/// rest of Legacy monolite core code (to be refactored ) BEGIN /// - case CH_RELAY: - { - short iaddr=getArg(); - short icmd =cmd.getCmd(); + // UPDATE internal variables + if (status2Send) cmd.saveItem(this,status2Send); + //debugSerial<0) - { - pinMode(iaddr, OUTPUT); - - 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<name); - tStore.tempX100=cmd.getFloat()*100.; //Save measurement - tStore.timestamp16=millisNZ(8) & 0xFFFF; //And timestamp - debugSerial<Ctrl(cmd, subItem, toExecute); + if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE; + //if (res==-1) status2Send=0; ///////not working + if (status2Send & FLAG_FLAGS) res =1; //ENABLE & DISABLE processed by core + } + else + { + switch (itemType) { + /// rest of Legacy monolite core code (to be refactored ) BEGIN /// + case CH_RELAY: + if (cmd.isCommand()) { - int vol; - if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())=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); - status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE; - }; + pinMode(iaddr, OUTPUT); - 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<name); + tStore.tempX100=cmd.getFloat()*100.; //Save measurement + tStore.timestamp16=millisNZ(8) & 0xFFFF; //And timestamp + debugSerial<=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<subtype=0; } @@ -1430,7 +1618,7 @@ void Item::sendDelayedStatus() int Item::SendStatus(int sendFlags) { if (sendFlags & FLAG_SEND_IMMEDIATE) sendFlags &= ~ (FLAG_SEND_IMMEDIATE | FLAG_SEND_DEFFERED); if ((sendFlags & FLAG_SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) { - setFlag(sendFlags & (FLAG_COMMAND | FLAG_PARAMETERS)); + setFlag(sendFlags & (FLAG_COMMAND | FLAG_PARAMETERS | FLAG_FLAGS)); debugSerial<name, sizeof(addrstr)-1); @@ -1501,7 +1690,7 @@ int Item::SendStatus(int sendFlags) { mqttClient.publish(addrstr, valstr, true); debugSerial<")<")<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<")<clearFlag(FLAG_DISABLED); + item->clearFlag(FLAG_FREEZED); break; + case CMD_FREEZE: + item->setFlag(FLAG_FREEZED); + break; + + case CMD_UNFREEZE: + item->clearFlag(FLAG_FREEZED); + break; } if (optionsFlag & FLAG_COMMAND) switch (cmd.cmdCode) { case CMD_DISABLE: case CMD_ENABLE: + case CMD_FREEZE: + case CMD_UNFREEZE: break; default: item->setCmd(cmd.cmdCode); diff --git a/lighthub/itemCmd.h b/lighthub/itemCmd.h index 6cc6aad..4034891 100644 --- a/lighthub/itemCmd.h +++ b/lighthub/itemCmd.h @@ -26,8 +26,10 @@ typedef char cmdstr[9]; const cmdstr commands_P[] PROGMEM = { "","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE", -"HEAT","COOL","AUTO","FAN_ONLY","DRY","STOP","HIGH","MEDIUM","LOW","ENABLE","DISABLE", -"TRUE","FALSE","RGB","HSV" +"ENABLE","DISABLE","UNFREEZE","FREEZE", +"AUTO","FAN_ONLY", +"HIGH","MEDIUM","LOW", +"HEAT","COOL","DRY","STOP","RGB","HSV" }; #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_UP 8 /// increase #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_AUTO 0xc /// Thermostat/AC set to Auto mode -#define CMD_FAN 0xd /// AC set to Fan-only mode -#define CMD_DRY 0xe /// AC set to Dry mode -#define CMD_STOP 0xf /// stop dimming (for further use) + +#define CMD_ENABLE 0xa /// for PID regulator and XON/XOFF - chan limitation +#define CMD_DISABLE 0xb /// for PID regulator +#define CMD_UNFREEZE 0xc /// Aliase for ON +#define CMD_FREEZE 0xd /// Aliase for OFF + +#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_MED 0x11 /// AC/Vent fan level MEDIUM #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_TRUE 0x15 /// Aliase for ON -#define CMD_FALSE 0x16 /// Aliase for OFF + +#define CMD_HEAT 0x13 /// Thermostat/AC set to HEATing mode +#define CMD_COOL 0x14 /// Thermostat/AC set to COOLing mode +#define CMD_DRY 0x15 /// AC set to Dry mode +#define CMD_STOP 0x16 /// stop dimming (for further use) + #define CMD_RGB 0x17 #define CMD_HSV 0x18 @@ -78,7 +84,7 @@ const cmdstr commands_P[] PROGMEM = #define FLAG_ACTION_IN_PROCESS 0x8000UL #define FLAG_DISABLED 0x10000UL -#define FLAG_DISABLED_ALL 0x20000UL +#define FLAG_FREEZED 0x20000UL #define FLAG_HALTED 0x40000UL #define FLAG_XON 0x80000UL diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 6dd419b..a6bd161 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -39,8 +39,8 @@ e-mail anklimov@gmail.com Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_BSD); static char syslogDeviceHostname[16]; - #if defined(debugSerialPort) - Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog); + #if defined(debugSerialPort) && !defined(NOSERIAL) + Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog); Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED); Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog); #else @@ -50,7 +50,7 @@ static char syslogDeviceHostname[16]; #endif #else - #if defined(debugSerialPort) + #if defined(debugSerialPort) && !defined(NOSERIAL) Streamlog debugSerial(&debugSerialPort,LOG_DEBUG); Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED); Streamlog infoSerial (&debugSerialPort,LOG_INFO); @@ -139,6 +139,7 @@ bool owReady = false; bool configOk = false; // At least once connected to MQTT bool configLoaded = false; bool initializedListeners = false; +uint8_t DHCP_failures = 0; volatile int8_t ethernetIdleCount =0; volatile int8_t configLocked = 0; @@ -762,7 +763,8 @@ lan_status lanLoop() { wdt_dis(); if (lanStatus >= HAVE_IP_ADDRESS) { - int etherStatus = Ethernet.maintain(); + int etherStatus = 0; + if (!DHCP_failures) etherStatus = Ethernet.maintain(); #ifndef Wiz5500 #define NO_LINK 5 @@ -1108,7 +1110,11 @@ if (WiFi.status() == WL_CONNECTED) { IPAddress ip, dns, gw, mask; int res = 1; infoSerial<= DHCP_ATTEMPTS_FALLBACK)) + ) + { infoSerial<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){ char s_mode[10]; @@ -177,11 +203,11 @@ byte getCRC(byte req[], size_t size){ } void out_AC::SendData(byte req[], size_t size){ - AC_Serial.write(req, size - 1); - AC_Serial.write(getCRC(req, size-1)); - //AC_Serial.flush(); + ACSerial->write(req, size - 1); + ACSerial->write(getCRC(req, size-1)); + //ACSerial->flush(); item->setExt(millisNZ()); - debugSerial.print("AirCon<<"); + debugSerial<begin(9600); +item->itemArr->subtype = CST_INITIALIZED; +//driverStatus = CST_INITIALIZED; return 1; } int out_AC::Stop() { -debugSerial<itemArr->subtype = CST_UNKNOWN; return 1; } int out_AC::Status() { -return driverStatus; +if (!item) return 0; +return item->itemArr->subtype; } int out_AC::isActive() @@ -240,16 +273,34 @@ if (cause!=POLLING_SLOW) return false; SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера } - if(AC_Serial.available() >= 37){ //was 0 - AC_Serial.readBytes(data, 37); - while(AC_Serial.available()){ + if(ACSerial->available() >= 37){ //was 0 + ACSerial->readBytes(data, 37); + while(ACSerial->available()){ delay(2); - AC_Serial.read(); + ACSerial->read(); } + +debugSerial<> "); + 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){ inCheck = data[36]; InsertData(data, 37); + debugSerial<write(data, 37); + ACSerial->flush(); publishTopic("RAW", buf); } */ @@ -474,12 +525,12 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute) data[9] = 1; data[10] = 77; data[11] = 95; - AC_Serial.flush(); + ACSerial->flush(); uint32_t ts=item->getExt(); while (ts && !isTimeOver(ts,millis(),100)) yield(); SendData(data, sizeof(data)/sizeof(byte)); //InsertData(data, sizeof(data)/sizeof(byte)); - //AC_Serial.flush(); + //ACSerial->flush(); //item->setExt(millisNZ()); return 1; } diff --git a/lighthub/modules/out_ac.h b/lighthub/modules/out_ac.h index 441f081..5035f95 100644 --- a/lighthub/modules/out_ac.h +++ b/lighthub/modules/out_ac.h @@ -24,7 +24,8 @@ extern void modbusIdle(void) ; class out_AC : public abstractOut { public: - out_AC(Item * _item):abstractOut(_item){}; + out_AC(Item * _item):abstractOut(_item){getConfig();}; + void getConfig(); int Setup() override; int Poll(short cause) override; int Stop() override; @@ -33,9 +34,16 @@ public: int getChanType() override; int getDefaultStorageType(){return ST_FLOAT_CELSIUS;}; int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override; - + protected: void InsertData(byte data[], size_t size); void SendData(byte req[], size_t size); + uint8_t portNum; + #if defined (__SAM3X8E__) + UARTClass *ACSerial; + #else + HardwareSerial *ACSerial; + #endif + }; #endif diff --git a/lighthub/modules/out_modbus.cpp b/lighthub/modules/out_modbus.cpp index c4cb0c3..bdde64a 100644 --- a/lighthub/modules/out_modbus.cpp +++ b/lighthub/modules/out_modbus.cpp @@ -358,8 +358,10 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,paramObj->name); if (execObj) { + aJsonObject * markObj = execObj; + if (execObj->type == aJson_Array) markObj = execObj->child; //Retrive previous data - aJsonObject *lastMeasured = aJson.getObjectItem(execObj,"@S"); + aJsonObject *lastMeasured = aJson.getObjectItem(markObj,"@S"); if (lastMeasured) { 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 { debugSerial<name<type==aJson_Int && (settedValue->valueint == param)) { debugSerial<parameters, paramName); - if (!templateParamObj) return -1; + if (!templateParamObj) {errorSerial<itemArg, 2); if (itemParametersObj && itemParametersObj->type ==aJson_Object) { 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)) { - 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) { modbusBusy=1; @@ -571,7 +581,7 @@ if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenc if (itemParametersObj && itemParametersObj->type ==aJson_Object) { 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 & 0x3) >= MB_SEND_ATTEMPTS) @@ -667,7 +677,7 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2); if (itemParametersObj && itemParametersObj->type ==aJson_Object) { 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"); @@ -680,7 +690,10 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object) { //Schedule update 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 { 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 { debugSerial<name<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 } diff --git a/lighthub/modules/out_motor.cpp b/lighthub/modules/out_motor.cpp index 74d3fac..79f8db8 100644 --- a/lighthub/modules/out_motor.cpp +++ b/lighthub/modules/out_motor.cpp @@ -50,7 +50,7 @@ int out_Motor::Setup() { abstractOut::Setup(); getConfig(); -debugSerial.println("Motor Init"); +debugSerial.println("Motor: Init"); pinMode(pinUp,OUTPUT); pinMode(pinDown,OUTPUT); @@ -70,7 +70,7 @@ return 1; int out_Motor::Stop() { -debugSerial.println("Motor De-Init"); +debugSerial.println("Motor: De-Init"); digitalWrite(pinUp,INACTIVE); digitalWrite(pinDown,INACTIVE); @@ -145,13 +145,13 @@ if (curPos>255) curPos=255; } if (motorOfftime && isTimeOver(motorOfftime,millis(),maxOnTime)) - {dif = 0; debugSerial<=0) dif=targetPos-curPos; else dif=targetPos-255/2; // Have No feedback -debugSerial<")<")<setExt(0); @@ -263,10 +263,7 @@ int out_Motor::getChanType() int out_Motor::Ctrl(itemCmd cmd, char* subItem , bool toExecute) { -//int chActive = item->isActive(); -//bool toExecute = (chActive>0); 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 item->setFlag(FLAG_ACTION_NEEDED); @@ -276,30 +273,15 @@ switch(suffixCode) case S_NOTFOUND: // turn on and set toExecute = true; -debugSerial<setVal(cmd.getPercents()); 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; //break; case S_CMD: - //item->setCmd(cmd.getCmd()); switch (cmd.getCmd()) { case CMD_ON: @@ -307,7 +289,6 @@ case S_CMD: return 1; case CMD_OFF: - ////item->SendStatus(FLAG_COMMAND); if (item->getExt()) item->setExt(millisNZ()); //Extend motor time return 1; diff --git a/lighthub/modules/out_multivent.cpp b/lighthub/modules/out_multivent.cpp index e221ac4..168d366 100644 --- a/lighthub/modules/out_multivent.cpp +++ b/lighthub/modules/out_multivent.cpp @@ -97,6 +97,7 @@ int out_Multivent::getChanType() 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(); 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:")<child; //Pass 2: re-distribute airflow @@ -250,11 +254,11 @@ while (i) debugSerial<name<<(" Req:")<valueint) + + if ((out != outObj->valueint)) { //report out - executeCommand(i,-1,itemCmd().Percents255(out)); + executeCommand(i,-1,itemCmd().Percents255(out)); outObj->valueint=out; } } @@ -262,37 +266,6 @@ while (i) } return 1; - -switch(suffixCode) -{ -case S_NOTFOUND: - // turn on and set -toExecute = true; -debugSerial<setCmd(cmd.getCmd()); - switch (cmd.getCmd()) - { - case CMD_ON: - - return 1; - - case CMD_OFF: - - return 1; - -} //switch cmd - -break; -} //switch suffix -debugSerial<itemArg, 0); if (!kPIDObj || kPIDObj->type != aJson_Array) { - errorSerial<pid->SetOutputLimits(outMin,outMax); store->pid->SetSampleTime(dT*1000.0); return true;} - else errorSerial<pid=NULL; //store->timestamp=millis(); if (getConfig()) { - infoSerial<itemArr->name<itemArr->name<On(); // Turn ON pid by default // if (item->getCmd()) item->setFlag(FLAG_COMMAND); // if (item->itemVal) item->setFlag(FLAG_PARAMETERS); @@ -129,7 +129,7 @@ if (getConfig()) return 1; } else - { errorSerial<driverStatus = CST_FAILED; return 0; } @@ -138,7 +138,7 @@ else int out_pid::Stop() { -debugSerial.println("PID De-Init"); +debugSerial.println("PID: De-Init"); if (store) delete (store->pid); delete store; item->setPersistent(NULL); @@ -163,30 +163,33 @@ int out_pid::Poll(short cause) { if (cause==POLLING_SLOW) return 0; if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCmd()!=CMD_OFF)) - { - //double prevOut=store->output; - //itemCmd st; - //st.loadItem(item); - //short cmd = st.getCmd(); - if (item->getCmd() != CMD_OFF && /* item->getCmd() != CMD_DISABLE*/ ! item->getFlag(FLAG_DISABLED)) + { + if (item->getCmd() != CMD_OFF && ! item->getFlag(FLAG_DISABLED)) { if(store->pid->Compute() ) { float alarmVal; if (store->alarmArmed && ((alarmVal=getAlarmVal())>=0.)) store->output=alarmVal; - debugSerial<itemArr->name<setpoint<input<<(" out:") << store->output <pid->GetKp() <pid->GetKi() <pid->GetKd(); - if (store->alarmArmed) debugSerial << F(" Alarm"); + + debugSerial<itemArr->name<setpoint<input<<(" out:") << store->output <pid->GetKp() <pid->GetKi() <pid->GetKd(); + //if (item->getFlag(FLAG_DISABLED)) debugSerial << F(" "); + if (store->alarmArmed) debugSerial << F(" "); debugSerial<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); - 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)); - 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); executeCommand(oCmd,-1,value); store->prevOut=store->output; @@ -198,7 +201,8 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm alarm(true); } } - } + } + return 1;//store->pollingInterval; }; @@ -208,7 +212,7 @@ float out_pid::getAlarmVal() aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0); if (!kPIDObj || kPIDObj->type != aJson_Array) { - errorSerial<input=cmd.getFloat(); -debugSerial<input<itemArr->name <input<alarmTimer=millis(); if (store->alarmArmed) @@ -309,11 +313,11 @@ return 1; case S_NOTFOUND: case S_SET: -//case S_ESET: + // Setpoint for PID if (!cmd.isValue()) return 0; store->setpoint=cmd.getFloat(); -debugSerial<setpoint<itemArr->name <setpoint<itemArg, 2); @@ -345,11 +349,14 @@ case S_CTRL: case CMD_DRY: executeCommand(oCmd,-1,value); + executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE)); + item->SendStatus(FLAG_FLAGS); return 1; case CMD_ENABLE: //item->setCmd(CMD_ENABLE); //item->SendStatus(FLAG_COMMAND); + item->setFlag(FLAG_ACTION_NEEDED); executeCommand(oCmd,-1,value); store->prevOut=-2.0; return 1; diff --git a/lighthub/options.h b/lighthub/options.h index 8efe5b6..cfc7e86 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -1,7 +1,7 @@ #pragma once #include - +#define DHCP_ATTEMPTS_FALLBACK 3 #define TENS_FRACT_LEN 2 #define TENS_BASE 100 @@ -138,12 +138,22 @@ #define MODBUS_SERIAL_BAUD 9600 #endif -#ifndef MODBUS_DIMMER_PARAM -#define MODBUS_DIMMER_PARAM SERIAL_8N1 +#ifndef MODBUS_SERIAL_PARAM +#define MODBUS_SERIAL_PARAM SERIAL_8N1 #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 #define SERIAL_BAUD 115200 @@ -303,7 +313,7 @@ //#ifdef M5STACK //#define debugSerial M5.Lcd //#endif -#ifdef noSerial +#ifdef NOSERIAL #undef debugSerialPort #else #ifndef debugSerialPort @@ -346,3 +356,9 @@ //#define PINS_COUNT NUM_DIGITAL_PINS #define isAnalogPin(p) ((p >= 14) && (p<=21)) #endif + +#ifdef AVR +#define minimalMemory 200 +#else +#define minimalMemory 1200 +#endif \ No newline at end of file diff --git a/lighthub/streamlog.cpp b/lighthub/streamlog.cpp index 2d25285..dd71974 100644 --- a/lighthub/streamlog.cpp +++ b/lighthub/streamlog.cpp @@ -30,7 +30,7 @@ Streamlog::Streamlog (SerialPortType * _serialPort, uint8_t _severity, uint8_t severity=_severity; } #endif - +/* void Streamlog::begin(unsigned long speed) { if (serialPort) serialPort->begin(speed); @@ -40,6 +40,7 @@ void Streamlog::end() { if (serialPort) serialPort->end(); }; +*/ int Streamlog::available(void) { @@ -79,7 +80,7 @@ if (syslogInitialized && (udpDebugLevel>=severity)) } else { - if (logBufferPos=severity)) #if defined (STATUSLED) if ((ch=='\n') && ledPattern) statusLED.flash(ledPattern); #endif - - if (serialPort && (serialDebugLevel>=severity)) return serialPort->write(ch); - + #if !defined(noSerial) + if (serialPort && (serialDebugLevel>=severity)) serialPort->write(ch); + #endif return 1; }; diff --git a/lighthub/streamlog.h b/lighthub/streamlog.h index 918c790..9556b54 100644 --- a/lighthub/streamlog.h +++ b/lighthub/streamlog.h @@ -36,8 +36,8 @@ class Streamlog : public Print #else Streamlog (SerialPortType * _serialPort, uint8_t _severity = LOG_DEBUG, uint8_t _ledPattern = 0); #endif - void begin(unsigned long speed); - void end() ; + //void begin(unsigned long speed); + //void end() ; int available(void); int peek(void); diff --git a/lighthub/systemconfigdata.h b/lighthub/systemconfigdata.h index 9fcf247..38db231 100644 --- a/lighthub/systemconfigdata.h +++ b/lighthub/systemconfigdata.h @@ -27,7 +27,8 @@ const char EEPROM_signature[] = EEPROM_SIGNATURE; uint8_t notGetConfigFromHTTP:1; uint8_t udpDebugLevel:3; uint8_t notSaveSuccedConfig:1; - uint8_t spare2; + uint8_t dhcpFallback:1; + uint8_t spare2:7; uint16_t sysConfigHash; }; } systemConfigFlags; diff --git a/lighthub/textconst.h b/lighthub/textconst.h index b3967dd..60dd33c 100644 --- a/lighthub/textconst.h +++ b/lighthub/textconst.h @@ -114,7 +114,8 @@ const char LOW_P[] PROGMEM = "LOW"; const char ERROR_P[] PROGMEM = "ERR"; const char ENABLE_P[] PROGMEM = "ENABLE"; const char DISABLE_P[] PROGMEM = "DISABLE"; - +const char FREEZE_P[] PROGMEM = "FREEZE"; +const char UNFREEZE_P[] PROGMEM = "UNFREEZE"; // SubTopics const char SET_P[] PROGMEM = "set"; diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 6ad2805..400074c 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -207,7 +207,7 @@ unsigned long freeRam() { extern char _end; extern "C" char *sbrk(int i); -unsigned long freeRam() { +unsigned long freeRam() { char *ramstart = (char *) 0x20070000; char *ramend = (char *) 0x20088000; char *heapend = sbrk(0); @@ -719,6 +719,13 @@ switch (cmdType) Item it(item->valuestring); if (it.isValid()) { + int fr = freeRam(); + if (fr < minimalMemory) + { + errorSerial<