From 0770e32b317161abaab79fdf8d175c12cbc1d66c Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 7 Mar 2024 00:52:33 +0300 Subject: [PATCH] CAN driver v1 ESP&STM --- lighthub/candriver.cpp | 65 ++++++++++++++++++++++++++++++++++++++---- lighthub/candriver.h | 5 ++-- lighthub/inputs.cpp | 35 +++++++++++++++++++++-- lighthub/item.cpp | 57 +++++++++++++++++++++++++++++++++++- lighthub/item.h | 1 + lighthub/itemCmd.cpp | 31 ++++++++++++++++++-- lighthub/itemCmd.h | 1 + lighthub/utils.cpp | 32 +++++++++++++++------ lighthub/utils.h | 2 +- 9 files changed, 206 insertions(+), 23 deletions(-) diff --git a/lighthub/candriver.cpp b/lighthub/candriver.cpp index a66b91e..2497445 100644 --- a/lighthub/candriver.cpp +++ b/lighthub/candriver.cpp @@ -348,8 +348,22 @@ if (id.status) } else //Requests { + if ((id.payloadType == payloadType::itemCommand) && (len ==8)) + { + Item it(id.itemId); + if (it.isValid()) + { + itemCmd ic; + ic.cmd = packet->cmd; + ic.param = packet->param; - if ((id.payloadType == payloadType::lookupMAC) && (len>=6)) + debugSerial<=6)) { return sendRemoteID(packet->mac); //debugSerial<<"ID requested"<type == aJson_Array)) + { + aJsonObject * dev = aJson.getArrayItem(can,0); + aJsonObject * it = aJson.getArrayItem(can,1); + debugSerial<valueint << ":" << it->valueint<type == aJson_Int && it->type == aJson_Int) + return sendCommand(dev->valueint, it->valueint, cmd, status); + } + return false; +} + +bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status) +{ + canid_t id; + datagram_t packet; + bool res; + + + id.reserve=0; + id.status=status?1:0; + id.payloadType=payloadType::itemCommand; + id.deviceId=devID; + id.itemId=itemID; + + packet.cmd = cmd.cmd; + packet.param = cmd.param; + + debugSerial << ((status)?"CAN: Status":"CAN: Command"); + debugSerial< +extern canDriver LHCAN; +#endif + #ifdef MCP23017 #include "Adafruit_MCP23X17.h" Adafruit_MCP23X17 mcp; @@ -626,6 +631,7 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<state && cause!=CHECK_INTERRUPT) debugSerial<state=newState; store->delayedState=false; - executeCommand(cmd,toggle,defCmd,defaultItem,defaultEmit); + executeCommand(cmd,toggle,defCmd,defaultItem,defaultEmit,defaultCan); return true; } else @@ -954,7 +960,8 @@ void Input::onContactChanged(int newValue) { aJsonObject *item = aJson.getObjectItem(inputObj, "item"); aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); - if (!item && !emit) return; + aJsonObject *can = aJson.getObjectItem(inputObj, "can"); + if (!item && !emit && !can) return; aJsonObject *scmd = aJson.getObjectItem(inputObj, "scmd"); aJsonObject *rcmd = aJson.getObjectItem(inputObj, "rcmd"); debugSerial << F("LEGACY IN:") << (pin) << F("=") << newValue << endl; @@ -1002,6 +1009,22 @@ if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestri } } } + + #ifdef CANDRV + + if (can) + { + if (newValue) { //send set command + if (!scmd || scmd->type != aJson_String) LHCAN.sendCommand(can,itemCmd(ST_VOID,CMD_ON)); + else if (strlen(scmd->valuestring)) LHCAN.sendCommand(can,itemCmd(scmd->valuestring)); + + } else { //send reset command + if (!rcmd || rcmd->type != aJson_String) LHCAN.sendCommand(can,itemCmd(ST_VOID,CMD_OFF)); + else if (strlen(rcmd->valuestring)) LHCAN.sendCommand(can,itemCmd(rcmd->valuestring)); + + } + } + #endif } @@ -1015,7 +1038,6 @@ void Input::onAnalogChanged(itemCmd newValue) { // Legacy aJsonObject *item = aJson.getObjectItem(inputObj, "item"); aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); - #if not defined (NOIP) if (emit && emit->type == aJson_String) { @@ -1039,6 +1061,13 @@ void Input::onAnalogChanged(itemCmd newValue) { Item it(item->valuestring); if (it.isValid()) it.Ctrl(newValue); } + + #ifdef CANDRV + aJsonObject *can = aJson.getObjectItem(inputObj, "can"); + if (can) LHCAN.sendCommand(can, newValue); + #endif + + } diff --git a/lighthub/item.cpp b/lighthub/item.cpp index d67805d..23230d4 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -67,6 +67,11 @@ e-mail anklimov@gmail.com #include "modules/out_humidifier.h" #endif +#ifdef CANDRV +#include +extern canDriver LHCAN; +#endif + short modbusBusy = 0; //bool isPendedModbusWrites = false; @@ -315,7 +320,52 @@ Item::Item(char *name) //Constructor Parse(); } +uint8_t getCanNum(aJsonObject* verb) + { + if (!verb) return 0; + switch (verb->type) + { + case aJson_Array: + { + aJsonObject *canNumObj=aJson.getArrayItem(verb,1); + if (canNumObj->type == aJson_Int) return canNumObj->valueint; + return 0; + } + case aJson_Object: + { + aJsonObject *canNumObj=aJson.getObjectItem(verb, "can"); + if (canNumObj->type == aJson_Int) return canNumObj->valueint; + return 0; + } + } + return 0; + } + Item::Item(uint16_t num) + { + + itemArr = NULL; + itemArg = NULL; + itemVal = NULL; + itemExt = NULL; + + driver = NULL; + defaultSubItem[0] =0; + defaultSuffixCode = 0; + + if (!items) return; + itemArr = items->child; + while (itemArr) + { + if (getCanNum(itemArr->child) == num) + { + debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl; + Parse(); + return; + } + itemArr = itemArr->next; + } + } uint8_t Item::getCmd() { aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD); if (t) @@ -1737,6 +1787,11 @@ int Item::SendStatus(int sendFlags) { char cmdstr[9] = ""; //debugSerial<<"SSI "<child),st); + #endif + if (sendFlags & FLAG_COMMAND) { // Preparing legacy Command payload ////////////// @@ -1953,7 +2008,7 @@ int Item::SendStatus(int sendFlags) { setFlag(sendFlags); return 0; } - #endif + #endif //NOIP } return 1; } diff --git a/lighthub/item.h b/lighthub/item.h index 08578c9..5a50a41 100644 --- a/lighthub/item.h +++ b/lighthub/item.h @@ -108,6 +108,7 @@ class Item Item(char * name); Item(aJsonObject * obj); + Item(uint16_t num); ~Item(); boolean isValid (); diff --git a/lighthub/itemCmd.cpp b/lighthub/itemCmd.cpp index 3f5a12a..29ffd2e 100644 --- a/lighthub/itemCmd.cpp +++ b/lighthub/itemCmd.cpp @@ -94,6 +94,23 @@ itemCmd::itemCmd(Item *item) loadItem(item); } +/*! + \brief Constructor with textual definition of command + \param cmd - name of cmd +todo - extend to values +*/ +itemCmd::itemCmd(char * _cmd) +{ + cmd.aslong=0; + param.aslong=0; + cmd.itemArgType=ST_VOID; +int i=0; +while (_cmd[i]) {_cmd[i]=toupper(_cmd[i]);i++;}; + +int cmdN = txt2cmd(_cmd); +if (cmdN == CMD_UNKNOWN) return; +cmd.cmdCode=cmdN; +} itemCmd itemCmd::setChanType(short chanType) { @@ -1196,8 +1213,14 @@ return false; int replaceTypeToInt(aJsonObject* verb) { - if (verb && verb->type == aJson_String) - { + if (!verb) return -1; + switch (verb->type) + { + case aJson_Int: return verb->valueint; + case aJson_Array: return replaceTypeToInt(verb->child); + case aJson_Object: return replaceTypeToInt(aJson.getObjectItem(verb, "type")); + case aJson_String: + { int type = type2num(verb->valuestring); if (type>=0) { @@ -1206,7 +1229,9 @@ return false; verb->type=aJson_Int; return verb->valueint; } - } else if (verb && verb->type == aJson_Int) return verb->valueint; + } + break; + } return -1; } diff --git a/lighthub/itemCmd.h b/lighthub/itemCmd.h index ef0dcc4..5810e87 100644 --- a/lighthub/itemCmd.h +++ b/lighthub/itemCmd.h @@ -204,6 +204,7 @@ public: itemCmd(uint8_t _type=ST_VOID, uint8_t _code=CMD_VOID); itemCmd(float val); itemCmd(Item *item); + itemCmd(char *cmd); itemCmd assignFrom(itemCmd from, short chanType=-1); diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 908fb90..a3450b7 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -33,6 +33,11 @@ extern int8_t ethernetIdleCount; #include #include "templateStr.h" +#ifdef CANDRV +#include +extern canDriver LHCAN; +#endif + #ifdef CRYPT #include "SHA256.h" #endif @@ -640,12 +645,13 @@ bool executeCommand(aJsonObject* cmd, int8_t toggle) return executeCommand(cmd,toggle,itemCmd()); } -bool executeCommand(aJsonObject* cmd, int8_t toggle, itemCmd _itemCmd, aJsonObject* defaultItem, aJsonObject* defaultEmit) +bool executeCommand(aJsonObject* cmd, int8_t toggle, itemCmd _itemCmd, aJsonObject* defaultItem, aJsonObject* defaultEmit, aJsonObject* defaultCan) //bool executeCommand(aJsonObject* cmd, int8_t toggle, char* defCmd) { //char * legacyString =NULL; aJsonObject *item = NULL; aJsonObject *emit = NULL; +aJsonObject *can = NULL; aJsonObject *icmd = NULL; aJsonObject *ecmd = NULL; char cmdType = 0; @@ -660,7 +666,7 @@ switch (cmdType) aJsonObject * command = cmd->child; while (command) { - executeCommand(command,toggle,_itemCmd,defaultItem,defaultEmit); + executeCommand(command,toggle,_itemCmd,defaultItem,defaultEmit,defaultCan); command = command->next; } configLocked--; @@ -674,8 +680,7 @@ switch (cmdType) item = aJson.getObjectItem(cmd, "item"); emit = aJson.getObjectItem(cmd, "emit"); - - + can = aJson.getObjectItem(cmd, "can"); switch (toggle) { case 0: @@ -699,6 +704,7 @@ switch (cmdType) { if (!item) item = defaultItem; if (!emit) emit = defaultEmit; + if (!can) can = defaultCan; char * itemCommand = NULL; char Buffer[16]; @@ -733,7 +739,7 @@ switch (cmdType) - + #if not defined (NOIP) if (emit && emitCommand && emit->type == aJson_String) { templateStream ts(emit->valuestring,suffix); @@ -757,14 +763,14 @@ switch (cmdType) //strncpy(addrstr,emit->valuestring,sizeof(addrstr)); - #if not defined (NOIP) + if (mqttClient.connected() && !ethernetIdleCount) { if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); mqttClient.publish(addrstr, emitCommand , true); } - #endif - } // emit +} // emit + #endif //NOIP if (item && item->type == aJson_String) { //debugSerial <valuestring <