CAN driver v1 ESP&STM

This commit is contained in:
2024-03-07 00:52:33 +03:00
parent 535e1be274
commit 0770e32b31
9 changed files with 206 additions and 23 deletions

View File

@@ -348,8 +348,22 @@ if (id.status)
} }
else //Requests 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<<F("CAN: received ");
ic.debugOut();
return it.Ctrl(ic);
}
return false;
}
else if ((id.payloadType == payloadType::lookupMAC) && (len>=6))
{ {
return sendRemoteID(packet->mac); return sendRemoteID(packet->mac);
//debugSerial<<"ID requested"<<endl; //debugSerial<<"ID requested"<<endl;
@@ -497,13 +511,54 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
bool canDriver::sendStatus(char * itemName, itemCmd cmd) bool canDriver::sendStatus(uint8_t itemNum, itemCmd cmd)
{ {
if (!itemNum) return false;
return sendCommand(controllerId, itemNum, cmd, true);
} }
bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd)
{
bool canDriver::sendCommand(aJsonObject * can,itemCmd cmd, bool status)
{
debugSerial<<"CAN: sendCommand ";
cmd.debugOut();
if (can && (can->type == aJson_Array))
{
aJsonObject * dev = aJson.getArrayItem(can,0);
aJsonObject * it = aJson.getArrayItem(can,1);
debugSerial<<dev->valueint << ":" << it->valueint<<endl;
if (dev && it && dev->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<<F(" for dev:item ")<<devID<<":"<<itemID<<" ";
cmd.debugOut();
res=write (id.id,&packet,8);
if (res) debugSerial<<F(" ok")<<endl;
else debugSerial<<F(" fail")<<endl;
return res;
} }

View File

@@ -111,8 +111,9 @@ class canDriver
public: public:
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::Unknown;}; canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::Unknown;};
uint8_t getMyId(); uint8_t getMyId();
bool sendStatus(char * itemName, itemCmd cmd); bool sendStatus(uint8_t itemNum, itemCmd cmd);
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd); bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false);
bool sendCommand(aJsonObject * can,itemCmd cmd, bool status = false);
bool upTime(uint32_t ut); bool upTime(uint32_t ut);
bool salt(uint32_t salt); bool salt(uint32_t salt);
bool lookupMAC(); bool lookupMAC();

View File

@@ -35,6 +35,11 @@ e-mail anklimov@gmail.com
#endif #endif
#endif #endif
#ifdef CANDRV
#include <candriver.h>
extern canDriver LHCAN;
#endif
#ifdef MCP23017 #ifdef MCP23017
#include "Adafruit_MCP23X17.h" #include "Adafruit_MCP23X17.h"
Adafruit_MCP23X17 mcp; Adafruit_MCP23X17 mcp;
@@ -626,6 +631,7 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
aJsonObject *defaultItem = aJson.getObjectItem(inputObj, "item"); aJsonObject *defaultItem = aJson.getObjectItem(inputObj, "item");
aJsonObject *defaultEmit = aJson.getObjectItem(inputObj, "emit"); aJsonObject *defaultEmit = aJson.getObjectItem(inputObj, "emit");
aJsonObject *defaultCan = aJson.getObjectItem(inputObj, "can");
if (!defaultEmit && !defaultItem) defCmd.Cmd(CMD_VOID); if (!defaultEmit && !defaultItem) defCmd.Cmd(CMD_VOID);
@@ -641,7 +647,7 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
{ {
store->state=newState; store->state=newState;
store->delayedState=false; store->delayedState=false;
executeCommand(cmd,toggle,defCmd,defaultItem,defaultEmit); executeCommand(cmd,toggle,defCmd,defaultItem,defaultEmit,defaultCan);
return true; return true;
} }
else else
@@ -954,7 +960,8 @@ void Input::onContactChanged(int newValue) {
aJsonObject *item = aJson.getObjectItem(inputObj, "item"); aJsonObject *item = aJson.getObjectItem(inputObj, "item");
aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); 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 *scmd = aJson.getObjectItem(inputObj, "scmd");
aJsonObject *rcmd = aJson.getObjectItem(inputObj, "rcmd"); aJsonObject *rcmd = aJson.getObjectItem(inputObj, "rcmd");
debugSerial << F("LEGACY IN:") << (pin) << F("=") << newValue << endl; 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 // Legacy
aJsonObject *item = aJson.getObjectItem(inputObj, "item"); aJsonObject *item = aJson.getObjectItem(inputObj, "item");
aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); aJsonObject *emit = aJson.getObjectItem(inputObj, "emit");
#if not defined (NOIP) #if not defined (NOIP)
if (emit && emit->type == aJson_String) { if (emit && emit->type == aJson_String) {
@@ -1039,6 +1061,13 @@ void Input::onAnalogChanged(itemCmd newValue) {
Item it(item->valuestring); Item it(item->valuestring);
if (it.isValid()) it.Ctrl(newValue); if (it.isValid()) it.Ctrl(newValue);
} }
#ifdef CANDRV
aJsonObject *can = aJson.getObjectItem(inputObj, "can");
if (can) LHCAN.sendCommand(can, newValue);
#endif
} }

View File

@@ -67,6 +67,11 @@ e-mail anklimov@gmail.com
#include "modules/out_humidifier.h" #include "modules/out_humidifier.h"
#endif #endif
#ifdef CANDRV
#include <candriver.h>
extern canDriver LHCAN;
#endif
short modbusBusy = 0; short modbusBusy = 0;
//bool isPendedModbusWrites = false; //bool isPendedModbusWrites = false;
@@ -315,7 +320,52 @@ Item::Item(char *name) //Constructor
Parse(); 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() { uint8_t Item::getCmd() {
aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD); aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD);
if (t) if (t)
@@ -1737,6 +1787,11 @@ int Item::SendStatus(int sendFlags) {
char cmdstr[9] = ""; char cmdstr[9] = "";
//debugSerial<<"SSI "<<subItem<<endl; //debugSerial<<"SSI "<<subItem<<endl;
st.debugOut(); st.debugOut();
#ifdef CANDRV
LHCAN.sendStatus(getCanNum(itemArr->child),st);
#endif
if (sendFlags & FLAG_COMMAND) if (sendFlags & FLAG_COMMAND)
{ {
// Preparing legacy Command payload ////////////// // Preparing legacy Command payload //////////////
@@ -1953,7 +2008,7 @@ int Item::SendStatus(int sendFlags) {
setFlag(sendFlags); setFlag(sendFlags);
return 0; return 0;
} }
#endif #endif //NOIP
} }
return 1; return 1;
} }

View File

@@ -108,6 +108,7 @@ class Item
Item(char * name); Item(char * name);
Item(aJsonObject * obj); Item(aJsonObject * obj);
Item(uint16_t num);
~Item(); ~Item();
boolean isValid (); boolean isValid ();

View File

@@ -94,6 +94,23 @@ itemCmd::itemCmd(Item *item)
loadItem(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) itemCmd itemCmd::setChanType(short chanType)
{ {
@@ -1196,7 +1213,13 @@ return false;
int replaceTypeToInt(aJsonObject* verb) 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); int type = type2num(verb->valuestring);
if (type>=0) if (type>=0)
@@ -1206,7 +1229,9 @@ return false;
verb->type=aJson_Int; verb->type=aJson_Int;
return verb->valueint; return verb->valueint;
} }
} else if (verb && verb->type == aJson_Int) return verb->valueint; }
break;
}
return -1; return -1;
} }

View File

@@ -204,6 +204,7 @@ public:
itemCmd(uint8_t _type=ST_VOID, uint8_t _code=CMD_VOID); itemCmd(uint8_t _type=ST_VOID, uint8_t _code=CMD_VOID);
itemCmd(float val); itemCmd(float val);
itemCmd(Item *item); itemCmd(Item *item);
itemCmd(char *cmd);
itemCmd assignFrom(itemCmd from, short chanType=-1); itemCmd assignFrom(itemCmd from, short chanType=-1);

View File

@@ -33,6 +33,11 @@ extern int8_t ethernetIdleCount;
#include <HardwareSerial.h> #include <HardwareSerial.h>
#include "templateStr.h" #include "templateStr.h"
#ifdef CANDRV
#include <candriver.h>
extern canDriver LHCAN;
#endif
#ifdef CRYPT #ifdef CRYPT
#include "SHA256.h" #include "SHA256.h"
#endif #endif
@@ -640,12 +645,13 @@ bool executeCommand(aJsonObject* cmd, int8_t toggle)
return executeCommand(cmd,toggle,itemCmd()); 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) //bool executeCommand(aJsonObject* cmd, int8_t toggle, char* defCmd)
{ {
//char * legacyString =NULL; //char * legacyString =NULL;
aJsonObject *item = NULL; aJsonObject *item = NULL;
aJsonObject *emit = NULL; aJsonObject *emit = NULL;
aJsonObject *can = NULL;
aJsonObject *icmd = NULL; aJsonObject *icmd = NULL;
aJsonObject *ecmd = NULL; aJsonObject *ecmd = NULL;
char cmdType = 0; char cmdType = 0;
@@ -660,7 +666,7 @@ switch (cmdType)
aJsonObject * command = cmd->child; aJsonObject * command = cmd->child;
while (command) while (command)
{ {
executeCommand(command,toggle,_itemCmd,defaultItem,defaultEmit); executeCommand(command,toggle,_itemCmd,defaultItem,defaultEmit,defaultCan);
command = command->next; command = command->next;
} }
configLocked--; configLocked--;
@@ -674,8 +680,7 @@ switch (cmdType)
item = aJson.getObjectItem(cmd, "item"); item = aJson.getObjectItem(cmd, "item");
emit = aJson.getObjectItem(cmd, "emit"); emit = aJson.getObjectItem(cmd, "emit");
can = aJson.getObjectItem(cmd, "can");
switch (toggle) switch (toggle)
{ {
case 0: case 0:
@@ -699,6 +704,7 @@ switch (cmdType)
{ {
if (!item) item = defaultItem; if (!item) item = defaultItem;
if (!emit) emit = defaultEmit; if (!emit) emit = defaultEmit;
if (!can) can = defaultCan;
char * itemCommand = NULL; char * itemCommand = NULL;
char Buffer[16]; char Buffer[16];
@@ -733,7 +739,7 @@ switch (cmdType)
#if not defined (NOIP)
if (emit && emitCommand && emit->type == aJson_String) { if (emit && emitCommand && emit->type == aJson_String) {
templateStream ts(emit->valuestring,suffix); templateStream ts(emit->valuestring,suffix);
@@ -757,14 +763,14 @@ switch (cmdType)
//strncpy(addrstr,emit->valuestring,sizeof(addrstr)); //strncpy(addrstr,emit->valuestring,sizeof(addrstr));
#if not defined (NOIP)
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
{ {
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
mqttClient.publish(addrstr, emitCommand , true); mqttClient.publish(addrstr, emitCommand , true);
} }
#endif } // emit
} // emit #endif //NOIP
if (item && item->type == aJson_String) { if (item && item->type == aJson_String) {
//debugSerial <<F("Controlled item:")<< item->valuestring <<endl; //debugSerial <<F("Controlled item:")<< item->valuestring <<endl;
@@ -782,6 +788,16 @@ switch (cmdType)
else it.Ctrl(_itemCmd); else it.Ctrl(_itemCmd);
} }
} }
#ifdef CANDRV
if (can)
{
if (itemCommand) LHCAN.sendCommand(can, itemCmd(itemCommand));
else LHCAN.sendCommand(can, _itemCmd);
} //else debugSerial << "Exec: noCan"<< endl;
#endif
return true; return true;
} }
default: default:

View File

@@ -70,7 +70,7 @@ void softRebootFunc();
bool isTimeOver(uint32_t timestamp, uint32_t currTime, uint32_t time, uint32_t modulo = 0); bool isTimeOver(uint32_t timestamp, uint32_t currTime, uint32_t time, uint32_t modulo = 0);
//bool executeCommand(aJsonObject* cmd, int8_t toggle = -1, char* defCmd = NULL); //bool executeCommand(aJsonObject* cmd, int8_t toggle = -1, char* defCmd = NULL);
bool executeCommand(aJsonObject* cmd, int8_t toggle = -1); bool executeCommand(aJsonObject* cmd, int8_t toggle = -1);
bool executeCommand(aJsonObject* cmd, int8_t toggle, itemCmd _itemCmd, aJsonObject* defaultItem=NULL, aJsonObject* defaultEmit=NULL); bool executeCommand(aJsonObject* cmd, int8_t toggle, itemCmd _itemCmd, aJsonObject* defaultItem=NULL, aJsonObject* defaultEmit=NULL, aJsonObject* defaultCan = NULL);
itemCmd mapInt(int32_t arg, aJsonObject* map); itemCmd mapInt(int32_t arg, aJsonObject* map);
unsigned long millisNZ(uint8_t shift=0); unsigned long millisNZ(uint8_t shift=0);
serialParamType str2SerialParam(char * str); serialParamType str2SerialParam(char * str);