diff --git a/build-flags/build_flags_stm32 b/build-flags/build_flags_stm32 index a00350a..16d1315 100644 --- a/build-flags/build_flags_stm32 +++ b/build-flags/build_flags_stm32 @@ -12,6 +12,8 @@ -DENABLE_HWSERIAL1 -DdebugSerialPort=Serial1 +-D TIMER_INT + #-DFLASH_BASE_ADDRESS #-DFLASH_DATA_SECTOR diff --git a/build-flags/build_flags_stm32-noip b/build-flags/build_flags_stm32-noip index 263c950..78aa547 100644 --- a/build-flags/build_flags_stm32-noip +++ b/build-flags/build_flags_stm32-noip @@ -17,7 +17,7 @@ -D THERMOSTAT_CHECK_PERIOD=5000 -D ULTRASONIC - +-D TIMER_INT -DENABLE_HWSERIAL1 -DdebugSerialPort=Serial1 diff --git a/lighthub/abstractch.h b/lighthub/abstractch.h index 01d65d9..7f8bf3e 100644 --- a/lighthub/abstractch.h +++ b/lighthub/abstractch.h @@ -19,8 +19,8 @@ public: protected: -virtual int publishTopic(const char* topic, long value, const char* subtopic = NULL); -virtual int publishTopic(const char* topic, float value, const char* subtopic = NULL ); -virtual int publishTopic(const char* topic, const char * value, const char* subtopic = NULL); -//friend Input; +int publishTopic(const char* topic, long value, const char* subtopic = NULL); +int publishTopic(const char* topic, float value, const char* subtopic = NULL ); +int publishTopic(const char* topic, const char * value, const char* subtopic = NULL); + }; diff --git a/lighthub/abstractout.cpp b/lighthub/abstractout.cpp index e744500..45ec28f 100644 --- a/lighthub/abstractout.cpp +++ b/lighthub/abstractout.cpp @@ -1,5 +1,3 @@ - - #include "item.h" #include "abstractout.h" #include "itemCmd.h" diff --git a/lighthub/abstractout.h b/lighthub/abstractout.h index 5cde9ed..7140d0c 100644 --- a/lighthub/abstractout.h +++ b/lighthub/abstractout.h @@ -7,7 +7,9 @@ class Item; class chPersistent {}; class abstractOut : public abstractCh{ public: - abstractOut(Item * _item):abstractCh(){item=_item;}; + //abstractOut(Item * _item):abstractCh(){item=_item;}; + abstractOut():item(NULL){}; + virtual void link(Item * _item){item=_item;}; virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) =0; virtual int isActive(); virtual bool isAllowed(itemCmd cmd){return true;}; @@ -17,8 +19,10 @@ public: virtual int Status() override; virtual void setStatus(uint8_t status) override; int Setup() override; + Item * getItem() {return item;} protected: int pubAction(bool state); Item * item; }; + diff --git a/lighthub/candriver.cpp b/lighthub/candriver.cpp index 724e9cc..22e0c0f 100644 --- a/lighthub/candriver.cpp +++ b/lighthub/candriver.cpp @@ -522,16 +522,14 @@ else //Requests if ((id.payloadType == payloadType::itemCommand) && (len ==8)) { Item it(id.itemId,id.subItemId); - if (it.isValid()) - { - itemCmd ic; - ic.cmd = packet->cmd; - ic.param = packet->param; - //debugSerial<cmd; + ic.param = packet->param; + //debugSerial<=6)) { @@ -749,7 +747,17 @@ bool canDriver::sendCommand(aJsonObject * can, itemCmd cmd, bool status) int suffix=txt2subItem(sfx->valuestring); if (suffix) cmd.setSuffix(suffix); } - if (subItemObj && subItemObj->type==aJson_Int && subItemObj->valueint>=0 && subItemObj->valueint<63) subItem=subItemObj->valueint; + + if (subItemObj) + switch (subItemObj->type) + { + case aJson_Int: + if (subItemObj->valueint>=0 && subItemObj->valueintvalueint; + break; + case aJson_String: + int suffix=txt2cmd(subItemObj->valuestring); + if (suffix) subItem = suffix | SUBITEM_IS_COMMAND; + } if (dev && it && dev->type == aJson_Int && it->type == aJson_Int) return sendCommand(dev->valueint, it->valueint, cmd, status,subItem); diff --git a/lighthub/candriver.h b/lighthub/candriver.h index 999b736..652ac21 100644 --- a/lighthub/candriver.h +++ b/lighthub/candriver.h @@ -1,5 +1,6 @@ #pragma once #define NO_SUBITEM 63 +#define SUBITEM_IS_COMMAND 0x20 #ifdef CANDRV #if defined(ARDUINO_ARCH_STM32) diff --git a/lighthub/colorchannel.h b/lighthub/colorchannel.h index 26807d1..a0575d4 100644 --- a/lighthub/colorchannel.h +++ b/lighthub/colorchannel.h @@ -9,11 +9,13 @@ class colorChannel : public abstractOut { public: - colorChannel(Item * _item):abstractOut(_item) { + colorChannel():iaddr(0),numArgs(0) {}; + void link (Item * _item) { + abstractOut::link(_item); iaddr = item->getArg(); //Once retrieve and store base address if (iaddr<0) iaddr=-iaddr; numArgs = item->getArgCount(); // and how many addresses is configured - }; + }; int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized=false) override; //int getDefaultStorageType()override; virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) =0; diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 2f87202..49320fe 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -83,6 +83,7 @@ extern PubSubClient mqttClient; extern int8_t ethernetIdleCount; extern int8_t configLocked; extern lan_status lanStatus; +driverFactory df; int retrieveCode(char **psubItem); @@ -172,7 +173,8 @@ void Item::Parse() { if (cmdObj) itemExt = cmdObj->next; itemType = replaceTypeToInt (itemTypeObj); - + driver=df.getDriver(this); +/* switch (itemType) { #ifndef PWM_DISABLE @@ -265,14 +267,13 @@ void Item::Parse() { break; #endif default: ; - } + } */ // debugSerial << F(" Item:") << itemArr->name << F(" T:") << itemType << F(" =") << getArg() << endl; } } boolean Item::Setup() { - if (driver) { if (driver->Status()) driver->Stop(); @@ -287,7 +288,7 @@ else return false; } void Item::Stop() -{ +{ if (driver) { driver->Stop(); @@ -299,7 +300,7 @@ Item::~Item() { if (driver) { - delete driver; + df.freeDriver (this); } } @@ -356,7 +357,7 @@ uint16_t getCanNum(aJsonObject* verb) char * Item::getSubItemStrById(uint8_t subItem) { -if (subItem == NO_SUBITEM) return NULL; +if (subItem == NO_SUBITEM || (subItem | SUBITEM_IS_COMMAND)) return NULL; if (!itemArg) return NULL; aJsonObject * i = itemArg; if (i->type == aJson_Array) i=i->child; @@ -421,8 +422,16 @@ return NO_SUBITEM; { debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl; Parse(); - char * subItemStr = getSubItemStrById(subItem); - if (subItemStr) strncpy(defaultSubItem,subItemStr,sizeof(defaultSubItem)); + if (subItem | SUBITEM_IS_COMMAND) + { + subItem &=~ SUBITEM_IS_COMMAND; + if (subItemnext; @@ -899,8 +908,8 @@ bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool aut configLocked--; return true; //Not execution, just activity check. If any channel is active - return true } + } } - } break; case aJson_Object: case aJson_Array: @@ -1091,6 +1100,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized long status2Send = 0; uint8_t command2Set = 0; itemCmd originalCmd = cmd; + int subitemCmd = subitem2cmd(subItem); /// Common (GRP & NO GRP) commands switch (cmd.getCmd()) @@ -1228,6 +1238,13 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED; cmd.setSuffix(S_SET); } else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<isAllowed(cmd)) case CMD_HALT: case CMD_XOFF: digitalWrite(iaddr, k = (inverse) ? HIGH : LOW); + default: + k = -1; } /* if (inverse) @@ -1780,7 +1800,6 @@ int Item::isActive() { return -1; } int cmd = getCmd(); - if (driver) { short active = driver->isActive(); if (active >= 0) @@ -1905,7 +1924,6 @@ switch (cause) sendDelayedStatus(); } } - if (driver && driver->Status()) { return driver->Poll(cause); @@ -2186,7 +2204,7 @@ int Item::SendStatus(long sendFlags, char * subItem) { } int Item::getChanType() -{ +{ if (driver) return driver->getChanType(); return itemType; } @@ -2218,7 +2236,6 @@ int Item::checkRetry() { { // if last sending attempt of command was failed itemCmd val(ST_VOID,CMD_VOID); val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS); - if (driver) { clearFlag(FLAG_SEND_RETRY); // Clean retry flag @@ -2721,5 +2738,158 @@ int Item::checkModbusDimmer(int data) { } //if data changed return 1; } - #endif + +Item * driverFactory::getItem(Item * item) +{ +abstractOut * driver = findDriver(item); +if (driver) return driver->getItem(); +return NULL; +} + +abstractOut * driverFactory::findDriver(Item * item) +{ +if (!item || !item->isValid()) return NULL; +uint8_t itemType = item->itemType; +if (itemType>CH_MAX) return NULL; + +switch (itemType) +{ + case CH_RGBW: + case CH_RGB: + case CH_RGBWW: + itemType = CH_DIMMER; +} +return drivers[itemType]; +} + +void driverFactory::freeDriver(Item * item) +{ +if (item && item->driver) + { + abstractOut * driver = findDriver(item); + if (driver) + { + if (driver->getItem() == item) + item->driver->link(NULL); + else delete item->driver; + } + } +} + +abstractOut * driverFactory::getDriver(Item * item) +{ +if (!item || !item->isValid()) return NULL; +abstractOut * driver = findDriver(item); +if (driver) + { + if (driver->getItem()) driver = newDriver(item->itemType); + } + +else + { + driver = newDriver(item->itemType); + if (driver) drivers[item->itemType]=driver; + } + + +if (driver) driver->link(item); +return driver; +} + +abstractOut * driverFactory::newDriver(uint8_t itemType) + { + abstractOut * driver = NULL; +switch (itemType) + { +#ifndef PWM_DISABLE + case CH_PWM: + driver = new out_pwm ; + break; +#endif + +#ifndef DMX_DISABLE + case CH_DIMMER: + driver = new out_dmx ; + break; +#endif +#ifndef SPILED_DISABLE + case CH_SPILED: + driver = new out_SPILed ; + break; +#endif + +#ifndef AC_DISABLE + case CH_AC: + driver = new out_AC ; + break; +#endif + +#ifndef MOTOR_DISABLE + case CH_MOTOR: + driver = new out_Motor ; + break; +#endif + +#ifndef MBUS_DISABLE + case CH_MBUS: + driver = new out_Modbus ; + break; +#endif + +#ifndef PID_DISABLE + case CH_PID: + driver = new out_pid ; + break; +#endif + + +#ifndef RELAY_DISABLE + case CH_RELAYX: + driver = new out_relay ; + break; +#endif + +#ifndef MULTIVENT_DISABLE + case CH_MULTIVENT: + driver = new out_Multivent ; + break; +#endif + +#ifdef UARTBRIDGE_ENABLE + case CH_UARTBRIDGE: + driver = new out_UARTbridge ; +// debugSerial<100) par=100; + if (par<1) par=1; + break; + + default: return false; + } + param.colorTemp=par; + return true; + +} + itemCmd itemCmd::assignFrom(itemCmd from, short chanType) { @@ -1514,7 +1531,7 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100 if (!Buffer || !bufLen) return NULL; *Buffer=0; char * argPtr=Buffer; - if (isCommand() && (sendFlags & FLAG_COMMAND)) + if (isCommand() && (sendFlags & FLAG_COMMAND) && cmd.cmdCodegetPersistent(); getConfig();}; + out_AC():store(NULL){}; + void link(Item * _item){abstractOut::link(_item); if (_item) {store = (acPersistent *) item->getPersistent(); getConfig();} else store = NULL;}; void getConfig(); int Setup() override; int Poll(short cause) override; diff --git a/lighthub/modules/out_counter.h b/lighthub/modules/out_counter.h index 297c480..77861ca 100644 --- a/lighthub/modules/out_counter.h +++ b/lighthub/modules/out_counter.h @@ -8,8 +8,6 @@ class out_counter : public abstractOut { public: - - out_counter(Item * _item):abstractOut(_item){}; int Setup() override; int Poll(short cause) override; int Stop() override; diff --git a/lighthub/modules/out_dmx.h b/lighthub/modules/out_dmx.h index 53bf259..ac0051a 100644 --- a/lighthub/modules/out_dmx.h +++ b/lighthub/modules/out_dmx.h @@ -9,14 +9,10 @@ class out_dmx : public colorChannel { public: - - out_dmx(Item * _item):colorChannel(_item){}; int Setup() override; int Stop() override; int getChanType() override; -// int Ctrl(itemCmd cmd, char* subItem=NULL) override; -// int PixelCtrl(itemCmd cmd) override; virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false) override; protected: diff --git a/lighthub/modules/out_mercury.h b/lighthub/modules/out_mercury.h index 525576f..a5ca685 100644 --- a/lighthub/modules/out_mercury.h +++ b/lighthub/modules/out_mercury.h @@ -42,13 +42,15 @@ public: class out_Mercury : public abstractOut { public: - out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();}; + //out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();}; + out_Mercury():store(NULL){}; + void link(Item * _item){abstractOut::link(_item); if (_item) {store = (mercuryPersistent *) item->getPersistent();} else store = NULL;}; + int Setup() override; int Poll(short cause) override; int Stop() override; int getChanType() override; int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override; - //int getDefaultStorageType(){return ST_INT32;}; protected: diff --git a/lighthub/modules/out_modbus.cpp b/lighthub/modules/out_modbus.cpp index da7f6d6..8ea7c1d 100644 --- a/lighthub/modules/out_modbus.cpp +++ b/lighthub/modules/out_modbus.cpp @@ -451,7 +451,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin { mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut); executeWithoutCheck=true; - debugSerial<<"MBUSD: recurrent check res: "<<"SRO:"<getPersistent();}; + out_Modbus():store(NULL){}; + void link(Item * _item){abstractOut::link(_item); if (_item) {store = (mbPersistent *) item->getPersistent(); } else store = NULL;}; - out_Modbus(Item * _item):abstractOut(_item){store = (mbPersistent *) item->getPersistent();}; int Setup() override; int Poll(short cause) override; int Stop() override; diff --git a/lighthub/modules/out_motor.h b/lighthub/modules/out_motor.h index c3edc09..ad3899e 100644 --- a/lighthub/modules/out_motor.h +++ b/lighthub/modules/out_motor.h @@ -20,7 +20,9 @@ static int8_t motorQuote = MOTOR_QUOTE; class out_Motor : public abstractOut { public: - out_Motor(Item * _item):abstractOut(_item){getConfig();}; + //out_Motor(Item * _item):abstractOut(_item){getConfig();}; + //out_Motor(){}; + void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();}; int Setup() override; int Poll(short cause) override; int Stop() override; diff --git a/lighthub/modules/out_multivent.h b/lighthub/modules/out_multivent.h index 64cc8df..8058ab7 100644 --- a/lighthub/modules/out_multivent.h +++ b/lighthub/modules/out_multivent.h @@ -12,7 +12,9 @@ class out_Multivent : public abstractOut { public: - out_Multivent(Item * _item):abstractOut(_item){getConfig();}; + //out_Multivent(Item * _item):abstractOut(_item){getConfig();}; + //out_Multivent(){}; + void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();}; int Setup() override; int Poll(short cause) override; int Stop() override; diff --git a/lighthub/modules/out_pid.h b/lighthub/modules/out_pid.h index d82ad42..0987d27 100644 --- a/lighthub/modules/out_pid.h +++ b/lighthub/modules/out_pid.h @@ -25,7 +25,10 @@ public: class out_pid : public abstractOut { public: - out_pid(Item * _item):abstractOut(_item){store = (pidPersistent *) item->getPersistent();}; + //out_pid(Item * _item):abstractOut(_item){store = (pidPersistent *) item->getPersistent();}; + out_pid():store(NULL){}; + void link(Item * _item){abstractOut::link(_item); if (_item) {store = (pidPersistent *) item->getPersistent();} else store = NULL;}; + int Setup() override; int Poll(short cause) override; int Stop() override; diff --git a/lighthub/modules/out_pwm.h b/lighthub/modules/out_pwm.h index 47305b7..c692e96 100644 --- a/lighthub/modules/out_pwm.h +++ b/lighthub/modules/out_pwm.h @@ -10,7 +10,7 @@ class out_pwm : public colorChannel { public: - out_pwm(Item * _item):colorChannel(_item){numChannels=0;}; +// out_pwm():numChannels(0){}; int Setup() override; int Stop() override; @@ -19,7 +19,7 @@ public: //int Ctrl(itemCmd cmd, char* subItem=NULL) override; int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) override; -protected: - short numChannels; +//protected: +// short numChannels; }; #endif diff --git a/lighthub/modules/out_relay.h b/lighthub/modules/out_relay.h index 07387b9..0bde632 100644 --- a/lighthub/modules/out_relay.h +++ b/lighthub/modules/out_relay.h @@ -8,8 +8,7 @@ class out_relay : public abstractOut { public: - - out_relay(Item * _item):abstractOut(_item){ getConfig();}; + void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();}; void getConfig(); void relay(bool state); int Setup() override; diff --git a/lighthub/modules/out_spiled.h b/lighthub/modules/out_spiled.h index c317d24..f584d84 100644 --- a/lighthub/modules/out_spiled.h +++ b/lighthub/modules/out_spiled.h @@ -15,7 +15,9 @@ class out_SPILed : public colorChannel { public: - out_SPILed(Item * _item):colorChannel(_item){getConfig();}; + //out_SPILed(Item * _item):colorChannel(_item){getConfig();}; + //out_SPILed(){}; + void link(Item * _item){colorChannel::link(_item);if (_item) getConfig();}; int Setup() override; int Stop() override; int getChanType() override; diff --git a/lighthub/modules/out_uartbridge.h b/lighthub/modules/out_uartbridge.h index 41312d7..bfd35bf 100644 --- a/lighthub/modules/out_uartbridge.h +++ b/lighthub/modules/out_uartbridge.h @@ -58,7 +58,12 @@ public: class out_UARTbridge : public abstractOut { public: - out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();}; + // out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();}; + + out_UARTbridge():store(NULL){}; + void link(Item * _item){abstractOut::link(_item); if (_item) {store = (ubPersistent *) item->getPersistent();} else store = NULL;}; + + int Setup() override; int Poll(short cause) override; int Stop() override; diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 0a8cff5..dd55fa7 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -130,7 +130,7 @@ long getIntFromStr(char **chan) { // chan is pointer to pointer to string // Function return first retrived number and move pointer to position next after ',' itemCmd getNumber(char **chan) { - itemCmd val(ST_TENS,CMD_VOID); + itemCmd val(ST_VOID,CMD_VOID); //WAS ST_TENS ? if (chan && *chan && **chan) { //Skip non-numeric values @@ -161,7 +161,7 @@ itemCmd getNumber(char **chan) { if (isDigit(*(fractptr+i))) fractnumbers += constrain(*(fractptr+i)-'0',0,9); } } - + if (!fractlen && !intlen) return val; //VOID if (!fractlen) val.Int(atol(*chan)); else if (fractlen<=TENS_FRACT_LEN && intlen+TENS_FRACT_LEN<=9) { @@ -670,11 +670,15 @@ aJsonObject *can = NULL; aJsonObject *icmd = NULL; aJsonObject *ecmd = NULL; char cmdType = 0; - -//char * out = aJson.print(cmd); -//debugSerial<<"Exec:"<=LOG_TRACE || udpDebugLevel>=LOG_TRACE) +{ +char* out = aJson.print(cmd); +if (out) +{ +debugSerial<<"Exec:"<type; switch (cmdType) diff --git a/platformio.ini b/platformio.ini index b5a584c..dab5ef0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1010,7 +1010,8 @@ lib_deps = https://github.com/anklimov/ModbusMaster pazi88/STM32_CAN ericksimoes/Ultrasonic - https://github.com/mathertel/RotaryEncoderv + https://github.com/mathertel/RotaryEncoder + ;TimerInterrupt_Generic monitor_speed = 115200