CAN driver - complete& working now

This commit is contained in:
2024-08-11 19:13:42 +03:00
parent 01ba615db8
commit 293429d3a3
7 changed files with 192 additions and 82 deletions

View File

@@ -29,7 +29,7 @@ extern bool configLoaded;
void printFrame(datagram_t * frame, uint8_t len ) { void printFrame(datagram_t * frame, uint8_t len ) {
debugSerial.print(" Data: 0x"); debugSerial.print(" Data:");
for (int count = 0; count < len; count++) { for (int count = 0; count < len; count++) {
debugSerial.print(frame->data[count], HEX); debugSerial.print(frame->data[count], HEX);
debugSerial.print(" "); debugSerial.print(" ");
@@ -40,7 +40,7 @@ void printFrame(datagram_t * frame, uint8_t len ) {
bool canDriver::upTime(uint32_t ut) bool canDriver::upTime(uint32_t ut)
{ {
// return 0; if (!controllerId) return false;
canid_t id; canid_t id;
datagram_t packet; datagram_t packet;
@@ -48,7 +48,8 @@ bool canDriver::upTime(uint32_t ut)
id.status=1; id.status=1;
id.payloadType=payloadType::metric; id.payloadType=payloadType::metric;
id.deviceId=controllerId; id.deviceId=controllerId;
id.itemId=metricType::UpTime; id.subjId=metricType::UpTime;
packet.metric1=ut; packet.metric1=ut;
@@ -58,6 +59,7 @@ bool canDriver::upTime(uint32_t ut)
bool canDriver::salt(uint32_t salt) bool canDriver::salt(uint32_t salt)
{ {
if (!controllerId) return false;
canid_t id; canid_t id;
datagram_t packet; datagram_t packet;
@@ -65,7 +67,9 @@ bool canDriver::salt(uint32_t salt)
id.status=1; id.status=1;
id.payloadType=payloadType::metric; id.payloadType=payloadType::metric;
id.deviceId=controllerId; id.deviceId=controllerId;
id.itemId=metricType::Salt; id.subjId=metricType::Salt;
packet.metric1=salt; packet.metric1=salt;
@@ -84,7 +88,9 @@ bool canDriver::lookupMAC()
id.status=0; id.status=0;
id.payloadType=payloadType::lookupMAC; id.payloadType=payloadType::lookupMAC;
id.deviceId=0; id.deviceId=0;
id.itemId=0; //CRC? id.subjId=0; //CRC?
memcpy(packet.mac,sysConf.mac,6); memcpy(packet.mac,sysConf.mac,6);
@@ -107,7 +113,9 @@ bool canDriver::requestFrame(uint8_t devId, payloadType _payloadType, uint16_t s
id.status=0; id.status=0;
id.payloadType=_payloadType; id.payloadType=_payloadType;
id.deviceId=devId; id.deviceId=devId;
id.itemId=seqNo; id.subjId=seqNo;
packet.metric1 =0; packet.metric1 =0;
//memcpy(packet.mac,sysConf.mac,6); //memcpy(packet.mac,sysConf.mac,6);
//delay (100); //delay (100);
@@ -131,7 +139,7 @@ bool canDriver::sendRemoteID(macAddress mac)
id.status=1; //response id.status=1; //response
id.payloadType=payloadType::lookupMAC; id.payloadType=payloadType::lookupMAC;
id.itemId=200; //CRC16 of remote config id.subjId=200; //CRC16 of remote config
//packet.data[0]=1; //packet.data[0]=1;
debugSerial<<("CAN: Send remote ID")<<endl; debugSerial<<("CAN: Send remote ID")<<endl;
@@ -144,6 +152,10 @@ return res;
bool canDriver::begin() bool canDriver::begin()
{
controllerId = getMyId();
if (!ready) // not reInitialization
{ {
ready=false; ready=false;
//STM32 //STM32
@@ -151,7 +163,7 @@ bool canDriver::begin()
//Can= new STM32_CAN( CAN1, ALT ); //Can= new STM32_CAN( CAN1, ALT );
//if (!Can) return false; //if (!Can) return false;
STMCan.begin(); //with retransmission STMCan.begin(); //with retransmission
STMCan.setBaudRate(125000); STMCan.setBaudRate(50000);
// STMCan.setFilter( 0, 0x153, 0x1FFFFFFF ); // STMCan.setFilter( 0, 0x153, 0x1FFFFFFF );
#endif #endif
@@ -159,11 +171,11 @@ bool canDriver::begin()
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
CAN.setPins(GPIO_NUM_35,GPIO_NUM_5);//(rx, tx); CAN.setPins(GPIO_NUM_35,GPIO_NUM_5);//(rx, tx);
// start the CAN bus at 500 kbps // start the CAN bus at 500 kbps
if (!CAN.begin(125000)) {return false; } if (!CAN.begin(50000)) {return false; }
#endif #endif
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
Can0.begin(CAN_BPS_125K); Can0.begin(CAN_BPS_50K);
int filter; int filter;
//extended //extended
@@ -172,10 +184,9 @@ bool canDriver::begin()
//Can1.setRXFilter(filter, 0, 0, true); //Can1.setRXFilter(filter, 0, 0, true);
} }
#endif #endif
debugSerial<<"CAN: initialized"<<endl;
controllerId = getMyId();
ready=true; ready=true;
}
debugSerial<<"CAN: initialized. addr="<<controllerId<<endl;
return true; return true;
} }
@@ -328,10 +339,49 @@ switch (state)
bool canDriver::processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr) bool canDriver::processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr)
{ {
debugSerial.print("CAN: Received "); debugSerial.print("CAN: Rcvd ");
debugSerial.print(len); debugSerial.print(len);
debugSerial.print(" bytes id 0x"); debugSerial.print(" bytes id:");
debugSerial.print(id.id,HEX); debugSerial.println(id.id,HEX);
if (id.deviceId && (id.deviceId != controllerId) && !id.status) return false;
debugSerial<<"CAN: " ;
if (id.status) debugSerial.print("Resp "); else debugSerial.print("Req ");
debugSerial<<"(devId:"<< id.deviceId <<" ";
switch ((id.payloadType)){
case payloadType::itemCommand:
debugSerial.print("itemCmd");
debugSerial<<" itemId:"<< id.itemId;
if (id.subItemId!=NO_SUBITEM) debugSerial << " subItem:"<<id.subItemId;
//debugSerial << ") ";
break;
case payloadType::lookupMAC:
debugSerial.print("lookupMAC");
break;
case payloadType::configFrame:
debugSerial.print("configFrame #");
debugSerial<< id.subjId;
break;
case payloadType::OTAFrame:
debugSerial.print("OTAFrame #");
debugSerial<< id.subjId;
break;
case payloadType::auth:
debugSerial.print("auth #");
debugSerial<< id.subjId;
break;
case payloadType::metric:
debugSerial.print("metric #");
debugSerial<< id.subjId;
break;
case payloadType::sysCmd:
debugSerial.print("sysCmd");
break;
case payloadType::rawPinCtrl:
debugSerial.print("rawPinCtrl");
}
debugSerial<< ") ";
if (len) printFrame(packet,len); if (len) printFrame(packet,len);
if (id.status){ if (id.status){
@@ -348,8 +398,8 @@ if (id.status){
debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl; debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl;
//char * itemNName = findItemName(id.itemId); //char * itemNName = findItemName(id.itemId);
aJsonObject *itemsObj = aJson.getObjectItem(confObj,"items"); aJsonObject *itemsObj = aJson.getObjectItem(confObj,"items");
if (!itemsObj) return false;; if (!itemsObj) return false;
Item it(id.itemId, itemsObj); Item it(id.itemId, id.subjId, itemsObj);
if (it.isValid()) if (it.isValid())
{ {
itemCmd ic; itemCmd ic;
@@ -363,7 +413,7 @@ if (id.status){
if (ic.isCommand()) flags |= FLAG_COMMAND; if (ic.isCommand()) flags |= FLAG_COMMAND;
if (ic.isValue()) flags |= FLAG_PARAMETERS; if (ic.isValue()) flags |= FLAG_PARAMETERS;
ic.saveItem(&it,flags); ic.saveItem(&it,flags);
it.SendStatusImmediate(ic,flags | FLAG_NOT_SEND_CAN); it.SendStatusImmediate(ic,flags | FLAG_NOT_SEND_CAN,it.getSubItemStrById(id.subItemId));
return true; return true;
} }
@@ -414,16 +464,15 @@ else //Requests
}*/ }*/
if ((id.payloadType == payloadType::itemCommand) && (len ==8)) if ((id.payloadType == payloadType::itemCommand) && (len ==8))
{ {
Item it(id.itemId); Item it(id.itemId,id.subItemId);
if (it.isValid()) if (it.isValid())
{ {
itemCmd ic; itemCmd ic;
ic.cmd = packet->cmd; ic.cmd = packet->cmd;
ic.param = packet->param; ic.param = packet->param;
//debugSerial<<F("CAN: itemCmd: ");
debugSerial<<F("CAN: received "); //ic.debugOut();
ic.debugOut(); return it.Ctrl(ic,it.getSubItemStrById(id.subItemId));
return it.Ctrl(ic);
} }
return false; return false;
} }
@@ -432,7 +481,7 @@ else //Requests
return sendRemoteID(packet->mac); return sendRemoteID(packet->mac);
//debugSerial<<"ID requested"<<endl; //debugSerial<<"ID requested"<<endl;
} }
else if ((id.payloadType == payloadType::configFrame) && (id.itemId == 0xFFFF)) else if ((id.payloadType == payloadType::configFrame) && (id.subjId == 0xFFFF))
{ {
debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl; debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl;
aJsonObject * remoteConfObj = findConfbyID(id.deviceId); aJsonObject * remoteConfObj = findConfbyID(id.deviceId);
@@ -575,24 +624,21 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
bool canDriver::sendStatus(uint8_t itemNum, itemCmd cmd) bool canDriver::sendStatus(uint16_t itemNum, itemCmd cmd, int subItem)
{ {
if (!itemNum) return false; if (!itemNum) return false;
return sendCommand(controllerId, itemNum, cmd, true); return sendCommand(controllerId, itemNum, cmd, true, subItem);
} }
bool canDriver::sendCommand(aJsonObject * can,itemCmd cmd, bool status) bool canDriver::sendCommand(aJsonObject * can, itemCmd cmd, bool status)
{ {
// debugSerial<<"CAN: ";
// if (status) debugSerial<<F("sendStatus ");
// else debugSerial<<F("sendCommand ");
// cmd.debugOut();
if (can && (can->type == aJson_Array)) if (can && (can->type == aJson_Array))
{ {
int subItem=NO_SUBITEM;
aJsonObject * dev = aJson.getArrayItem(can,0); aJsonObject * dev = aJson.getArrayItem(can,0);
aJsonObject * it = aJson.getArrayItem(can,1); aJsonObject * it = aJson.getArrayItem(can,1);
aJsonObject * sfx = aJson.getArrayItem(can,2); aJsonObject * sfx = aJson.getArrayItem(can,2);
aJsonObject * subItemObj = aJson.getArrayItem(can,3);
if (sfx) if (sfx)
switch (sfx->type) switch (sfx->type)
{ {
@@ -602,14 +648,15 @@ bool canDriver::sendCommand(aJsonObject * can,itemCmd cmd, bool status)
int suffix=txt2subItem(sfx->valuestring); int suffix=txt2subItem(sfx->valuestring);
if (suffix) cmd.setSuffix(suffix); if (suffix) cmd.setSuffix(suffix);
} }
debugSerial<<dev->valueint << ":" << it->valueint<<endl; if (subItemObj && subItemObj->type==aJson_Int && subItemObj->valueint>=0 && subItemObj->valueint<63) subItem=subItemObj->valueint;
if (dev && it && dev->type == aJson_Int && it->type == aJson_Int) if (dev && it && dev->type == aJson_Int && it->type == aJson_Int)
return sendCommand(dev->valueint, it->valueint, cmd, status); return sendCommand(dev->valueint, it->valueint, cmd, status,subItem);
} }
return false; return false;
} }
bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status) bool canDriver::sendCommand(uint8_t devID, uint16_t itemID,itemCmd cmd, bool status,int subItemID )
{ {
canid_t id; canid_t id;
datagram_t packet; datagram_t packet;
@@ -621,18 +668,20 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
id.payloadType=payloadType::itemCommand; id.payloadType=payloadType::itemCommand;
id.deviceId=devID; id.deviceId=devID;
id.itemId=itemID; id.itemId=itemID;
id.subItemId=subItemID;
packet.cmd = cmd.cmd; packet.cmd = cmd.cmd;
packet.param = cmd.param; packet.param = cmd.param;
debugSerial << ((status)?"CAN: send Status":"CAN: send Command"); debugSerial << ((status)?"CAN: send Status":"CAN: send Command");
debugSerial<<F(" for dev:item ")<<devID<<":"<<itemID<<" "; debugSerial<<F(" ->[")<<devID<<":"<<itemID<<"] ";
if (subItemID!=NO_SUBITEM) debugSerial<<F("Subitem:")<<subItemID<<" ";
cmd.debugOut(); cmd.debugOut();
res=write (id.id,&packet,8); res=write (id.id,&packet,8);
if (res) debugSerial<<F("CAN: sent ok")<<endl; //if (res) debugSerial<<F("CAN: sent ok")<<endl;
else debugSerial<<F("CAN: fail")<<endl; // else debugSerial<<F("CAN: fail")<<endl;
return res; return res;
} }
@@ -652,7 +701,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
id.status=1; id.status=1;
id.payloadType=pType; id.payloadType=pType;
id.deviceId=devId; id.deviceId=devId;
id.itemId=_seqNo; id.subjId=_seqNo;
res=driver->write (id.id, &writeBuffer, len); res=driver->write (id.id, &writeBuffer, len);
writePos=0; writePos=0;
@@ -695,8 +744,8 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
if ((c=driver->readFrame()>0) && (driver->RXid.deviceId == devId) && (driver ->RXid.payloadType == pType) && driver->RXid.status) if ((c=driver->readFrame()>0) && (driver->RXid.deviceId == devId) && (driver ->RXid.payloadType == pType) && driver->RXid.status)
{ {
state = canState::FrameReceived; state = canState::FrameReceived;
debugSerial<<F("CAN: Payload received ")<< c << "|" <<driver->RXlen<< " "<<driver->RXpacket.payload<<"#"<<driver->RXid.itemId<<endl; debugSerial<<F("CAN: Payload received ")<< c << "|" <<driver->RXlen<< " "<<driver->RXpacket.payload<<"#"<<driver->RXid.subjId<<endl;
seqNo=driver->RXid.itemId; seqNo=driver->RXid.subjId;
failedCount=0; failedCount=0;
return driver->RXlen; return driver->RXlen;
} }
@@ -729,8 +778,8 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
(driver->RXid.status == 0) (driver->RXid.status == 0)
) )
{ {
debugSerial<<F("CAN: frame confirmed #")<<driver->RXid.itemId<<endl; debugSerial<<F("CAN: frame confirmed #")<<driver->RXid.subjId<<endl;
if (seqNo == driver->RXid.itemId) if (seqNo == driver->RXid.subjId)
{ {
state = canState::StreamOpenedWrite; state = canState::StreamOpenedWrite;
seqNo++; seqNo++;

View File

@@ -21,8 +21,15 @@ typedef union
{ {
uint32_t id; uint32_t id;
struct struct
{ union
{ {
uint16_t itemId; struct
{
uint16_t subItemId:6;
uint16_t itemId:10;
};
uint16_t subjId;
};
uint8_t deviceId; uint8_t deviceId;
uint8_t payloadType:4; uint8_t payloadType:4;
uint8_t status:1; uint8_t status:1;
@@ -30,6 +37,7 @@ typedef union
}; };
} canid_t; } canid_t;
#define NO_SUBITEM 63
enum payloadType enum payloadType
{ unknown=0, { unknown=0,
@@ -112,8 +120,8 @@ class canDriver
public: public:
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;}; canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;};
uint8_t getMyId(); uint8_t getMyId();
bool sendStatus(uint8_t itemNum, itemCmd cmd); bool sendStatus(uint16_t itemNum, itemCmd cmd, int subItem = NO_SUBITEM);
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false); bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false, int subItemID=NO_SUBITEM );
bool sendCommand(aJsonObject * can,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);

View File

@@ -322,7 +322,7 @@ Item::Item(char *name, aJsonObject *_items) //Constructor
Parse(); Parse();
} }
uint8_t getCanNum(aJsonObject* verb) uint16_t getCanNum(aJsonObject* verb)
{ {
if (!verb) return 0; if (!verb) return 0;
switch (verb->type) switch (verb->type)
@@ -343,7 +343,52 @@ uint8_t getCanNum(aJsonObject* verb)
return 0; return 0;
} }
Item::Item(uint16_t num, aJsonObject *_items) char * Item::getSubItemStrById(uint8_t subItem)
{
if (subItem == NO_SUBITEM) return NULL;
if (!itemArg) return NULL;
aJsonObject * i = itemArg;
if (i->type == aJson_Array) i=i->child;
while (i)
{
if (i->type == aJson_Object)
{
aJsonObject * s = aJson.getArrayItem(i,subItem);
if (s && (s->type == aJson_Object)) return s->name;
return NULL;
}
i=i->next;
}
return NULL;
};
uint8_t Item::getSubitemId(char * subItem)
{
if (!subItem) return NO_SUBITEM;
if (!itemArg) return NO_SUBITEM;
aJsonObject * i = itemArg;
if (i->type == aJson_Array) i=i->child;
while (i)
{
if (i->type == aJson_Object)
{
aJsonObject *c = i->child;
uint8_t index=0;
while (c)
{
if (!strcasecmp(c->name, subItem)) return index;
c = c->next; index++;
}
return NO_SUBITEM;
}
i=i->next;
};
return NO_SUBITEM;
}
Item::Item(uint16_t num, uint8_t subItem, aJsonObject *_items)
{ {
itemArr = NULL; itemArr = NULL;
@@ -358,12 +403,15 @@ uint8_t getCanNum(aJsonObject* verb)
if (!rootItems) return; if (!rootItems) return;
itemArr = rootItems->child; itemArr = rootItems->child;
if (!num) return;
while (itemArr) while (itemArr)
{ {
if (getCanNum(itemArr->child) == num) if (getCanNum(itemArr->child) == num)
{ {
debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl; debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl;
Parse(); Parse();
char * subItemStr = getSubItemStrById(subItem);
if (subItemStr) strncpy(defaultSubItem,subItemStr,sizeof(defaultSubItem));
return; return;
} }
itemArr = itemArr->next; itemArr = itemArr->next;
@@ -1778,7 +1826,6 @@ 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 | FLAG_FLAGS); //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;
return SendStatusImmediate(st,sendFlags); return SendStatusImmediate(st,sendFlags);
} }
} }
@@ -1788,11 +1835,12 @@ int Item::SendStatus(int sendFlags) {
char addrstr[64]; char addrstr[64];
char valstr[20] = ""; char valstr[20] = "";
char cmdstr[9] = ""; char cmdstr[9] = "";
//debugSerial<<"SSI "<<subItem<<endl;
debugSerial<<"SENDSTATUS: "<<subItem;
st.debugOut(); st.debugOut();
#ifdef CANDRV #ifdef CANDRV
if (!(sendFlags & FLAG_NOT_SEND_CAN)) LHCAN.sendStatus(getCanNum(itemArr->child),st); if (!(sendFlags & FLAG_NOT_SEND_CAN)) LHCAN.sendStatus(getCanNum(itemArr->child),st, getSubitemId(subItem));
#endif #endif
if (sendFlags & FLAG_COMMAND) if (sendFlags & FLAG_COMMAND)
@@ -1821,7 +1869,7 @@ int Item::SendStatus(int sendFlags) {
break; break;
default: default:
debugSerial<<F("Unknown cmd \n"); debugSerial<<F("SENDSTATUS: Unknown cmd \n");
sendFlags &= ~FLAG_COMMAND; sendFlags &= ~FLAG_COMMAND;
} }
} }

View File

@@ -109,7 +109,7 @@ class Item
Item(char * name, aJsonObject *_items = items); Item(char * name, aJsonObject *_items = items);
Item(aJsonObject * obj, aJsonObject *_items = items); Item(aJsonObject * obj, aJsonObject *_items = items);
Item(uint16_t num, aJsonObject *_items = items); Item(uint16_t num, uint8_t subItem, aJsonObject *_items = items);
~Item(); ~Item();
boolean isValid (); boolean isValid ();
@@ -148,7 +148,8 @@ class Item
int scheduleCommand(itemCmd cmd, bool authorized); int scheduleCommand(itemCmd cmd, bool authorized);
int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized); int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized);
int isScheduled(); int isScheduled();
char * getSubItemStrById(uint8_t subItem);
uint8_t getSubitemId(char * subItem);
protected: protected:
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false); bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false);

View File

@@ -1231,6 +1231,7 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
break; break;
default: default:
item->setCmd(cmd.cmdCode); item->setCmd(cmd.cmdCode);
} }
if (optionsFlag & FLAG_PARAMETERS) if (optionsFlag & FLAG_PARAMETERS)
switch (cmd.itemArgType) switch (cmd.itemArgType)
@@ -1310,7 +1311,7 @@ return false;
{ {
case aJson_Array: case aJson_Array:
{ {
debugSerial<<"Array mapping"<<endl; traceSerial<<"Array mapping"<<endl;
aJsonObject *i = cmdMapping->child; aJsonObject *i = cmdMapping->child;
//if first array element is not array - this is default mapping value //if first array element is not array - this is default mapping value
if (i && i->type==aJson_Int) if (i && i->type==aJson_Int)

View File

@@ -157,10 +157,9 @@ typedef union
struct struct
{ {
uint8_t cmdCode; uint8_t cmdCode;
uint8_t suffixCode:4;
uint8_t itemArgType:4; uint8_t itemArgType:4;
uint8_t cmdEffect:4; //Reserve
uint8_t cmdEffect; //Reserve uint8_t suffixCode;
uint8_t cmdParam; //Reserve uint8_t cmdParam; //Reserve
}; };
} itemCmdStore; } itemCmdStore;

View File

@@ -1394,6 +1394,10 @@ topics = aJson.getObjectItem(root, "topics");
inputs = aJson.getObjectItem(root, "in"); inputs = aJson.getObjectItem(root, "in");
brokersArr = aJson.getObjectItem(root, "mqtt"); brokersArr = aJson.getObjectItem(root, "mqtt");
#ifdef CANDRV
LHCAN.begin(); //Applying updated CAN addr
#endif
if (brokersArr && brokersArr->child && (brokersArr->child->type == aJson_Array)) if (brokersArr && brokersArr->child && (brokersArr->child->type == aJson_Array))
{ {
infoSerial<<F("Brokers configured:")<<(brokers=aJson.getArraySize(brokersArr))<<endl; infoSerial<<F("Brokers configured:")<<(brokers=aJson.getArraySize(brokersArr))<<endl;