mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fae1bd4dcc | |||
| e5e24943a6 | |||
| f672878873 | |||
| ff8997fb02 | |||
| 96a9c59add | |||
| 7759d51b31 | |||
| e21541aa7a | |||
| 806e99eb92 | |||
| 2b638b1310 | |||
| 82f729216e | |||
| dc6e310b10 | |||
| baad75fde7 | |||
| 7040d9bf93 | |||
| 0a4e70479b |
Binary file not shown.
File diff suppressed because it is too large
Load Diff
2
compiled/Mega2560-optiboot/uploadOTA.sh
Executable file
2
compiled/Mega2560-optiboot/uploadOTA.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
../tools/mac/arduinoOTA -address 192.168.11.10 -port 80 -username arduino -password password -sketch firmware.bin -b -upload /sketch
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
../tools/mac/tool-avrdude/avrdude -C ../tools/mac/tool-avrdude/avrdude.conf -P net:192.168.88.2:23000 -v -V -patmega2560 -cwiring -b115200 -D -Uflash:w:firmware.hex:i
|
||||
avrdude -P net:192.168.88.2:23000 -v -V -patmega2560 -cwiring -b115200 -D -Uflash:w:firmware.hex:i
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -131,15 +131,19 @@ bool canDriver::sendRemoteID(macAddress mac)
|
||||
{
|
||||
canid_t id;
|
||||
//datagram_t packet;
|
||||
bool res=false;
|
||||
bool res=false;
|
||||
id.subjId=0;
|
||||
id.deviceId=getIdByMac(mac); //Retrieved controllerID
|
||||
if (!id.deviceId) return false;
|
||||
aJsonObject * config=getConfbyID(id.deviceId);
|
||||
if (config) id.subjId=getCRC(config); //CRC16 of remote config
|
||||
|
||||
id.reserve=0;
|
||||
id.status=1; //response
|
||||
id.payloadType=payloadType::lookupMAC;
|
||||
|
||||
id.subjId=200; //CRC16 of remote config
|
||||
|
||||
|
||||
|
||||
debugSerial<<("CAN: Send remote ID")<<endl;
|
||||
res = write (id.id,(datagram_t*)mac,6);
|
||||
@@ -152,7 +156,21 @@ return res;
|
||||
|
||||
bool canDriver::begin()
|
||||
{
|
||||
controllerId = getMyId();
|
||||
if (root)
|
||||
{
|
||||
canConfigObj = aJson.getObjectItem(root, "can");
|
||||
if (canConfigObj)
|
||||
{
|
||||
canRemoteConfigObj= aJson.getObjectItem(canConfigObj, "conf");
|
||||
controllerId = getMyId();
|
||||
}
|
||||
confCRC=getCRC(root);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NOIP
|
||||
if (!canConfigObj) return false;
|
||||
#endif
|
||||
|
||||
if (!ready) // not reInitialization
|
||||
{
|
||||
@@ -304,8 +322,8 @@ switch (state)
|
||||
|
||||
if (CANConfStream.peek() == '{') {
|
||||
debugSerial<<F("CAN: JSON detected")<<endl;
|
||||
cleanConf(1);
|
||||
aJsonStream as = aJsonStream(&CANConfStream);
|
||||
cleanConf(false);
|
||||
root = aJson.parse(&as);
|
||||
CANConfStream.close();
|
||||
if (!root) {
|
||||
@@ -318,7 +336,9 @@ switch (state)
|
||||
}
|
||||
infoSerial<<F("CAN: config Loaded")<<endl;
|
||||
configLocked--;
|
||||
applyConfig();
|
||||
cmdFunctionSave(0,NULL);
|
||||
if (applyConfig()) ;
|
||||
// debugSerial.print(aJson.print(root,false));
|
||||
sysConf.loadETAG();
|
||||
state = canState::Idle;
|
||||
return ;
|
||||
@@ -419,7 +439,7 @@ if (id.status){
|
||||
case payloadType::itemCommand:
|
||||
{
|
||||
if (len!=8) return false;
|
||||
aJsonObject *confObj = findConfbyID(id.deviceId);
|
||||
aJsonObject *confObj = getConfbyID(id.deviceId);
|
||||
if (confObj)
|
||||
{
|
||||
debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl;
|
||||
@@ -434,13 +454,15 @@ if (id.status){
|
||||
ic.cmd = packet->cmd;
|
||||
ic.param = packet->param;
|
||||
|
||||
debugSerial<<F("CAN: item ")<<it.itemArr->name;
|
||||
debugSerial<<F("CAN: item ")<<it.itemArr->name<<" ";
|
||||
ic.debugOut();
|
||||
|
||||
if (ic.isCommand()) flags |= FLAG_COMMAND;
|
||||
if (ic.isValue()) flags |= FLAG_PARAMETERS;
|
||||
if (ic.getSuffix()==S_DELAYED) flags |= FLAG_SEND_DELAYED;
|
||||
else if (ic.isCommand()) flags |= FLAG_COMMAND;
|
||||
|
||||
ic.saveItem(&it,flags);
|
||||
it.SendStatusImmediate(ic,flags | FLAG_NOT_SEND_CAN,it.getSubItemStrById(id.subItemId));
|
||||
it.SendStatusImmediate(ic,flags | FLAG_NOT_SEND_CAN, it.getSubItemStrById(id.subItemId));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -456,9 +478,17 @@ if (id.status){
|
||||
case canState::MACLookup:
|
||||
if ((id.payloadType == payloadType::lookupMAC))
|
||||
{
|
||||
debugSerial<<"\nCAN: Got Controller addr: "<<id.deviceId<<endl;
|
||||
controllerId=id.deviceId;
|
||||
state = canState::ReadConfig;
|
||||
if (root && (id.subjId == confCRC)) ///?
|
||||
{
|
||||
infoSerial << (F("Valid config already onboard")) << endl;
|
||||
state = canState::Idle;
|
||||
}
|
||||
else
|
||||
{
|
||||
infoSerial<<"\nCAN: Got Controller addr: "<<id.deviceId<<endl;
|
||||
state = canState::ReadConfig;
|
||||
controllerId=id.deviceId;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -511,7 +541,7 @@ else //Requests
|
||||
else if ((id.payloadType == payloadType::configFrame) && (id.subjId == 0xFFFF))
|
||||
{
|
||||
debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl;
|
||||
aJsonObject * remoteConfObj = findConfbyID(id.deviceId);
|
||||
aJsonObject * remoteConfObj = getConfbyID(id.deviceId);
|
||||
if (remoteConfObj)
|
||||
{
|
||||
infoSerial<<F("CAN: Sending conf for dev#")<<id.deviceId<<endl;
|
||||
@@ -531,26 +561,17 @@ return false;
|
||||
|
||||
uint8_t canDriver::getMyId()
|
||||
{
|
||||
if (!root) return 0;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return 0;
|
||||
|
||||
aJsonObject * addrObj = aJson.getObjectItem(canObj, "addr");
|
||||
if (!canConfigObj) return 0;
|
||||
aJsonObject * addrObj = aJson.getObjectItem(canConfigObj, "addr");
|
||||
if (addrObj && (addrObj->type == aJson_Int)) return addrObj->valueint;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
aJsonObject * canDriver::findConfbyID(uint8_t devId)
|
||||
aJsonObject * canDriver::getConfbyID(uint8_t devId)
|
||||
{
|
||||
if (!root) return NULL;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return NULL;
|
||||
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(canObj, "conf");
|
||||
|
||||
if (!remoteConfObj) return NULL;
|
||||
remoteConfObj=remoteConfObj->child;
|
||||
if (!canConfigObj) return NULL;
|
||||
if (!canRemoteConfigObj || canRemoteConfigObj->type != aJson_Object) return NULL;
|
||||
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
@@ -564,30 +585,77 @@ while (remoteConfObj)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aJsonObject * canDriver::findConfbyName(char* devName, int * devAddr)
|
||||
{
|
||||
if (!canRemoteConfigObj || canRemoteConfigObj->type != aJson_Object || !devName ) return NULL;
|
||||
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
if (remoteCanObj)
|
||||
{
|
||||
aJsonObject * nameObj = aJson.getObjectItem(remoteCanObj, "name");
|
||||
if (nameObj && (nameObj->type == aJson_String) && nameObj->valuestring && (strncasecmp(nameObj->valuestring,devName,strlen(nameObj->valuestring)) == 0))
|
||||
{
|
||||
if (devAddr)
|
||||
{
|
||||
aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "addr");
|
||||
if (addrObj && (addrObj->type == aJson_Int)) *devAddr=addrObj->valueint;
|
||||
}
|
||||
return remoteConfObj;
|
||||
}
|
||||
}
|
||||
remoteConfObj=remoteConfObj->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if not defined (NOIP)
|
||||
extern PubSubClient mqttClient;
|
||||
|
||||
bool canDriver::subscribeTopics(char * root, size_t buflen)
|
||||
{
|
||||
if (!root) return false;
|
||||
if (!canRemoteConfigObj || canRemoteConfigObj->type != aJson_Object) return false;
|
||||
|
||||
int rootLen = strlen(root);
|
||||
|
||||
aJsonObject * remoteConfObj=canRemoteConfigObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
if (remoteCanObj)
|
||||
{
|
||||
aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "name");
|
||||
if (addrObj && (addrObj->type == aJson_String) && addrObj->valuestring)
|
||||
{
|
||||
strncpy(root+rootLen, addrObj->valuestring, buflen-rootLen-1);
|
||||
strncat(root+rootLen, "/", buflen-rootLen-1);
|
||||
strncat(root+rootLen, "#", buflen-rootLen-1);
|
||||
debugSerial.println(root);
|
||||
mqttClient.subscribe(root);
|
||||
}
|
||||
}
|
||||
remoteConfObj=remoteConfObj->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t canDriver::getIdByMac(macAddress mac)
|
||||
{
|
||||
char macStr[19];
|
||||
uint8_t strptr = 0;
|
||||
char macStr[19];
|
||||
uint8_t strptr = 0;
|
||||
|
||||
if (!root) return 0;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return 0;
|
||||
aJsonObject * confObj = aJson.getObjectItem(canObj, "conf");
|
||||
if (!confObj) return 0;
|
||||
|
||||
memset(macStr,0,sizeof(macStr));
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
// if (mac[i]<16) macStr[strptr++]='0';
|
||||
|
||||
SetBytes(&mac[i],1,&macStr[strptr]);
|
||||
strptr+=2;
|
||||
|
||||
if (i < 5) macStr[strptr++]=':';
|
||||
}
|
||||
if (!canRemoteConfigObj) return 0;
|
||||
memset(macStr,0,sizeof(macStr));
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
SetBytes(&mac[i],1,&macStr[strptr]);
|
||||
strptr+=2;
|
||||
if (i < 5) macStr[strptr++]=':';
|
||||
}
|
||||
debugSerial<<F("CAN: Searching devId for ")<<macStr<<endl;
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(confObj, macStr);
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(canRemoteConfigObj, macStr);
|
||||
|
||||
if (!remoteConfObj) return 0;
|
||||
|
||||
@@ -606,8 +674,11 @@ return 0;
|
||||
}
|
||||
|
||||
bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
|
||||
{ //return 0;
|
||||
if (!ready) errorSerial<<"CAN: not initialized"<<endl;
|
||||
{ //
|
||||
if (!ready) {
|
||||
errorSerial<<"CAN: not initialized"<<endl;
|
||||
return false;
|
||||
}
|
||||
bool res;
|
||||
if (size>8) size = 8;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ Error
|
||||
class canDriver
|
||||
{
|
||||
public:
|
||||
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;};
|
||||
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;canConfigObj=NULL;canRemoteConfigObj=NULL;confCRC=0xFFFF;};
|
||||
uint8_t getMyId();
|
||||
bool sendStatus(uint16_t itemNum, itemCmd cmd, int subItem = NO_SUBITEM);
|
||||
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false, int subItemID=NO_SUBITEM );
|
||||
@@ -134,15 +134,22 @@ bool begin();
|
||||
void Poll();
|
||||
bool processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr=false);
|
||||
bool write(uint32_t msg_id, datagram_t * buf = NULL, uint8_t size=0);
|
||||
aJsonObject * findConfbyName(char* devName, int * devAddr=NULL);
|
||||
#if not defined (NOIP)
|
||||
bool subscribeTopics(char * root, size_t buflen);
|
||||
#endif
|
||||
|
||||
uint8_t getControllerID(){return controllerId;};
|
||||
uint8_t getIdByMac(macAddress mac);
|
||||
|
||||
aJsonObject * canConfigObj;
|
||||
aJsonObject * canRemoteConfigObj;
|
||||
uint16_t confCRC;
|
||||
datagram_t RXpacket;
|
||||
canid_t RXid;
|
||||
uint8_t RXlen;
|
||||
|
||||
private:
|
||||
aJsonObject * findConfbyID(uint8_t devId);
|
||||
aJsonObject * getConfbyID(uint8_t devId);
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
CAN_message_t CAN_RX_msg;
|
||||
|
||||
@@ -287,6 +287,10 @@ NRFFlashStorage EEPROM;
|
||||
putEOF();
|
||||
debugSerial<<F("EOF")<<endl;
|
||||
}
|
||||
#if defined (ARDUINO_ARCH_STM32)
|
||||
eeprom_buffer_flush();
|
||||
#endif
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
if (samBufferPos) flush();
|
||||
#endif
|
||||
|
||||
@@ -156,13 +156,23 @@ void Item::Parse() {
|
||||
if (isValid()) {
|
||||
// Todo - avoid static enlarge for every types
|
||||
for (int i = aJson.getArraySize(itemArr); i < 4; i++)
|
||||
aJson.addItemToArray(itemArr, aJson.createNull());//( (long int) 0));
|
||||
// int(defval[i]) )); //Enlarge item to 4 elements. VAL=int if no other definition in conf
|
||||
//itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint;
|
||||
aJson.addItemToArray(itemArr, aJson.createNull());
|
||||
|
||||
/*
|
||||
itemType = replaceTypeToInt (aJson.getArrayItem(itemArr, I_TYPE));
|
||||
itemArg = aJson.getArrayItem(itemArr, I_ARG);
|
||||
itemVal = aJson.getArrayItem(itemArr, I_VAL);
|
||||
itemExt = aJson.getArrayItem(itemArr, I_EXT);
|
||||
itemExt = aJson.getArrayItem(itemArr, I_EXT); */
|
||||
|
||||
aJsonObject * cmdObj = NULL;
|
||||
aJsonObject * itemTypeObj = itemArr->child;
|
||||
if (itemTypeObj) itemArg = itemTypeObj->next;
|
||||
if (itemArg) itemVal = itemArg->next;
|
||||
if (itemVal) cmdObj = itemVal->next;
|
||||
if (cmdObj) itemExt = cmdObj->next;
|
||||
|
||||
itemType = replaceTypeToInt (itemTypeObj);
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
#ifndef PWM_DISABLE
|
||||
@@ -331,13 +341,13 @@ uint16_t getCanNum(aJsonObject* verb)
|
||||
case aJson_Array:
|
||||
{
|
||||
aJsonObject *canNumObj=aJson.getArrayItem(verb,1);
|
||||
if (canNumObj->type == aJson_Int) return canNumObj->valueint;
|
||||
if (canNumObj && 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;
|
||||
if (canNumObj && canNumObj->type == aJson_Int) return canNumObj->valueint;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -649,7 +659,7 @@ if (suffix = strrchr(*psubItem, '/')) //Trying to retrieve right part
|
||||
*suffix= 0; //Truncate subItem string
|
||||
suffix++;
|
||||
suffixCode = txt2subItem(suffix);
|
||||
debugSerial<<F("suffixCode:")<<suffixCode<<endl;
|
||||
// debugSerial<<F("suffixCode:")<<suffixCode<<endl;
|
||||
// myhome/dev/item/sub.....Item/suffix
|
||||
}
|
||||
else
|
||||
@@ -684,7 +694,7 @@ long int Item::limitSetValue()
|
||||
|
||||
|
||||
// myhome/dev/item/subItem
|
||||
int Item::Ctrl(char * payload, char * subItem)
|
||||
int Item::Ctrl(char * payload, char * subItem, int remoteID)
|
||||
{
|
||||
if (!payload) return 0;
|
||||
int fr = freeRam();
|
||||
@@ -709,13 +719,16 @@ if (suffixCode == S_RAW)
|
||||
{ itemCmd ic;
|
||||
ic.Str(payload);
|
||||
ic.setSuffix(suffixCode);
|
||||
if (remoteID) return remoteCtrl(ic,remoteID,subItem);
|
||||
return Ctrl(ic,subItem);
|
||||
}
|
||||
|
||||
bool authorized = false;
|
||||
char * authPos = strchr(payload,'@');
|
||||
char * authToken = NULL;
|
||||
char * authPos = strchr(payload,'@'); //token@command
|
||||
if (authPos)
|
||||
{
|
||||
authToken = payload;
|
||||
*authPos=0;
|
||||
authorized = checkToken(payload,authPos+1);
|
||||
payload=authPos+1;
|
||||
@@ -782,7 +795,7 @@ st.setSuffix(suffixCode);
|
||||
default: errorSerial<<F("Wrong paylad")<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
|
||||
return Ctrl(st,subItem,true,authorized);
|
||||
} //Void command
|
||||
break;
|
||||
@@ -806,7 +819,7 @@ st.setSuffix(suffixCode);
|
||||
case 4: st.RGBW(Par[0],Par[1],Par[2],Par[3]);
|
||||
default:;
|
||||
}
|
||||
|
||||
if (remoteID) return remoteCtrl(st,remoteID,subItem,authToken);
|
||||
return Ctrl(st,subItem,true,authorized);
|
||||
}
|
||||
case CMD_UP:
|
||||
@@ -815,18 +828,40 @@ st.setSuffix(suffixCode);
|
||||
itemCmd Par0 = getNumber((char **) &payload);
|
||||
Par0.Cmd(cmd);
|
||||
Par0.setSuffix(suffixCode);
|
||||
if (remoteID) return remoteCtrl(Par0,remoteID,subItem,authToken);
|
||||
return Ctrl(Par0, subItem,true,authorized);
|
||||
}
|
||||
default: //some known command
|
||||
{
|
||||
int32_t intParam = getIntFromStr((char **) &payload);
|
||||
if (intParam) st.Int(intParam);
|
||||
if (remoteID) return remoteCtrl(st,remoteID,NULL,authToken);
|
||||
return Ctrl(st,NULL, true, authorized);
|
||||
}
|
||||
} //ctrl
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Item::remoteCtrl(itemCmd cmd, int remoteID, char* subItem, char * authToken)
|
||||
{
|
||||
#ifdef CANDRV
|
||||
// Retrieve remote item id
|
||||
if (!itemArr) return 0;
|
||||
aJsonObject * itemHandler = itemArr->child;
|
||||
if (!itemHandler || itemHandler->type!=aJson_Array) return 0;
|
||||
aJsonObject * itemIdObj=aJson.getArrayItem(itemHandler,1);
|
||||
if (itemIdObj->type != aJson_Int) return 0;
|
||||
|
||||
//Retrieve target controller ID
|
||||
if (!remoteID) return 0;
|
||||
|
||||
//TODO - translate subItem & auth token
|
||||
short subitemNum = NO_SUBITEM;
|
||||
return LHCAN.sendCommand(remoteID,itemIdObj->valueint,cmd,false,subitemNum);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Recursive function with small stack consumption
|
||||
// if cmd defined - execute Ctrl for any group members recursively
|
||||
// else performs Activity check for group members and return true if any member is active
|
||||
@@ -836,7 +871,9 @@ bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool aut
|
||||
aJsonObject *i = itemArr->child;
|
||||
configLocked++;
|
||||
while (i) {
|
||||
if (i->type == aJson_String)
|
||||
switch (i->type)
|
||||
{
|
||||
case aJson_String:
|
||||
{ //debugSerial<< i->valuestring<<endl;
|
||||
aJsonObject *nextItem = aJson.getObjectItem(rootItems, i->valuestring);
|
||||
if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item
|
||||
@@ -844,8 +881,9 @@ bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool aut
|
||||
Item it(nextItem);
|
||||
if (cmd && it.isValid()) it.Ctrl(*cmd,subItem,false,authorized); //Execute (non recursive)
|
||||
//Retrieve itemType
|
||||
aJsonObject * itemtype = aJson.getArrayItem(nextItem,0);
|
||||
if (itemtype && itemtype->type == aJson_Int && itemtype->valueint == CH_GROUP)
|
||||
//aJsonObject * itemtype = aJson.getArrayItem(nextItem,0);
|
||||
//if (itemtype && itemtype->type == aJson_Int && itemtype->valueint == CH_GROUP)
|
||||
if (it.itemType == CH_GROUP)
|
||||
{ //is Group
|
||||
aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1);
|
||||
short res = digGroup(itemSubArray,cmd,subItem,authorized);
|
||||
@@ -863,6 +901,11 @@ bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool aut
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case aJson_Object:
|
||||
case aJson_Array:
|
||||
executeCommand(i,-1,*cmd);
|
||||
}//switch
|
||||
i = i->next;
|
||||
} //while
|
||||
configLocked--;
|
||||
@@ -1663,7 +1706,7 @@ int Item::isActive() {
|
||||
itemCmd st;
|
||||
int val = 0;
|
||||
|
||||
debugSerial<<itemArr->name<<F(" ");
|
||||
debugSerial<<F("ACTIVE:")<<itemArr->name<<F(" ");
|
||||
if (!isValid())
|
||||
{
|
||||
debugSerial<<F(" invalid")<<endl;
|
||||
@@ -1841,7 +1884,8 @@ int Item::SendStatus(int sendFlags) {
|
||||
st.debugOut();
|
||||
|
||||
#ifdef CANDRV
|
||||
if (!(sendFlags & FLAG_NOT_SEND_CAN)) LHCAN.sendStatus(getCanNum(itemArr->child),st, getSubitemId(subItem));
|
||||
if (!(sendFlags & FLAG_NOT_SEND_CAN))
|
||||
LHCAN.sendStatus(getCanNum(itemArr->child),(sendFlags & FLAG_SEND_DELAYED)?st.setSuffix(S_DELAYED):st, getSubitemId(subItem));
|
||||
#endif
|
||||
|
||||
if (sendFlags & FLAG_COMMAND)
|
||||
|
||||
@@ -117,8 +117,8 @@ class Item
|
||||
void Stop();
|
||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool allowRecursion = true, bool authorized=false);
|
||||
int Ctrl(char * payload, char * subItem=NULL);
|
||||
|
||||
int Ctrl(char * payload, char * subItem=NULL, int remoteID = 0);
|
||||
int remoteCtrl(itemCmd cmd, int remoteID, char* subItem=NULL, char * authToken=NULL);
|
||||
int getArg(short n=0);
|
||||
float getFloatArg(short n=0);
|
||||
short getArgCount();
|
||||
|
||||
@@ -1454,7 +1454,9 @@ if (valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMappi
|
||||
|
||||
if (getInt()<aJson.getArrayItem(valMapping,2)->valueint) return itemCmd().Int((uint32_t) 0);
|
||||
int diff = ((b-a)/(d-c))/2;
|
||||
return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255));
|
||||
//return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255));
|
||||
return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,b));
|
||||
//return itemCmd().Int((uint32_t) map(getInt(),c,d,a,b)+diff);
|
||||
}
|
||||
if (valMapping && valMapping->type == aJson_NULL) return itemCmd();
|
||||
return *this;
|
||||
|
||||
@@ -115,24 +115,24 @@ UID UniqueID;
|
||||
#endif
|
||||
uint8_t brokers = 0;
|
||||
char *deviceName = NULL;
|
||||
aJsonObject *topics = NULL;
|
||||
aJsonObject *root = NULL;
|
||||
aJsonObject *items = NULL;
|
||||
aJsonObject *inputs = NULL;
|
||||
aJsonObject *brokersArr = NULL;
|
||||
aJsonObject *mqttArr = NULL;
|
||||
aJsonObject *topics = NULL;
|
||||
aJsonObject *root = NULL;
|
||||
aJsonObject *items = NULL;
|
||||
aJsonObject *inputs = NULL;
|
||||
aJsonObject *brokersArr = NULL;
|
||||
aJsonObject *mqttArr = NULL;
|
||||
#ifdef _modbus
|
||||
aJsonObject *modbusObj = NULL;
|
||||
aJsonObject *modbusObj = NULL;
|
||||
#endif
|
||||
#ifdef _owire
|
||||
aJsonObject *owArr = NULL;
|
||||
aJsonObject *owArr = NULL;
|
||||
#endif
|
||||
#ifdef _dmxout
|
||||
aJsonObject *dmxArr = NULL;
|
||||
aJsonObject *dmxArr = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef SYSLOG_ENABLE
|
||||
bool syslogInitialized = false;
|
||||
volatile bool syslogInitialized = false;
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_ENABLE
|
||||
@@ -153,11 +153,11 @@ volatile uint32_t ultrasonicInputCheck=0;
|
||||
|
||||
aJsonObject *pollingItem = NULL;
|
||||
|
||||
bool owReady = false;
|
||||
bool configOk = false; // At least once connected to MQTT
|
||||
bool configLoaded = false;
|
||||
bool initializedListeners = false;
|
||||
uint8_t DHCP_failures = 0;
|
||||
volatile bool owReady = false;
|
||||
volatile bool configOk = false; // At least once connected to MQTT
|
||||
volatile bool configLoaded = false;
|
||||
volatile bool initializedListeners = false;
|
||||
volatile uint8_t DHCP_failures = 0;
|
||||
volatile int8_t ethernetIdleCount =0;
|
||||
volatile int8_t configLocked = 0;
|
||||
|
||||
@@ -177,45 +177,19 @@ int8_t mqttErrorRate=0;
|
||||
void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE
|
||||
#endif
|
||||
|
||||
bool cleanConf(bool wait)
|
||||
bool cleanConf(short locksAlowed )
|
||||
{
|
||||
if (!root) return true;
|
||||
bool clean = true;
|
||||
if (configLocked)
|
||||
if (!root)
|
||||
{
|
||||
//debugSerial<<F("No root")<<endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (configLocked>locksAlowed)
|
||||
{
|
||||
errorSerial<<F("Can not clean - locked")<<endl;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
No more unsafe operations
|
||||
if (wait)
|
||||
{
|
||||
debugSerial<<F("Unlocking config ...")<<endl;
|
||||
uint32_t stamp=millis();
|
||||
while (configLocked && !isTimeOver(stamp,millis(),10000))
|
||||
{
|
||||
//wdt_res();
|
||||
cmdPoll();
|
||||
#ifdef _owire
|
||||
if (owReady && owArr) owLoop();
|
||||
#endif
|
||||
#ifdef _dmxin
|
||||
DMXCheck();
|
||||
#endif
|
||||
if (isNotRetainingStatus()) pollingLoop();
|
||||
thermoLoop();
|
||||
inputLoop(CHECK_INPUT);
|
||||
yield();
|
||||
}
|
||||
|
||||
if (configLocked)
|
||||
{
|
||||
errorSerial<<F("Not unlocked in 10s - continue ...")<<endl;
|
||||
clean = false;
|
||||
}
|
||||
} //wait
|
||||
*/
|
||||
|
||||
debugSerial<<F("Stopping channels ...")<<endl;
|
||||
timerHandlerBusy++;
|
||||
//Stoping the channels
|
||||
@@ -265,7 +239,7 @@ debugSerial<<F("Deleting conf. RAM was:")<<freeRam();
|
||||
|
||||
configOk=false;
|
||||
timerHandlerBusy--;
|
||||
return clean;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isNotRetainingStatus() {
|
||||
@@ -434,8 +408,11 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
|
||||
short pfxlen = 0;
|
||||
char * itemName = NULL;
|
||||
char * subItem = NULL;
|
||||
char savedTopic[MQTT_TOPIC_LENGTH] = "";
|
||||
bool forLocal=false;
|
||||
bool forBcast=false;
|
||||
aJsonObject * remoteConfig = NULL;
|
||||
int remoteID=0;
|
||||
|
||||
// in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant.
|
||||
if (lanStatus == RETAINING_COLLECTING)
|
||||
@@ -455,17 +432,53 @@ if (lanStatus == RETAINING_COLLECTING)
|
||||
}
|
||||
return;
|
||||
}
|
||||
else forLocal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfxlen=inTopic(topic,T_DEV);
|
||||
/* pfxlen=inTopic(topic,T_DEV);
|
||||
if (!pfxlen) pfxlen = inTopic(topic,T_BCST);
|
||||
else // Personal device topic
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1);
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1); //Save topic to delete after exec
|
||||
*/
|
||||
pfxlen=inTopic(topic,T_DEV);
|
||||
if (pfxlen)
|
||||
{
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1); //Save topic to delete after exec
|
||||
forLocal=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pfxlen = inTopic(topic,T_BCST);
|
||||
if (pfxlen) forBcast = true;
|
||||
}
|
||||
|
||||
|
||||
//if (pfxlen) forLocal=true;
|
||||
|
||||
#ifdef CANDRV
|
||||
// else //Nor local or bcst name, try can names
|
||||
if (!forLocal && !forBcast)
|
||||
{
|
||||
pfxlen=inTopic(topic,T_ROOT); //check root
|
||||
if (pfxlen)
|
||||
{
|
||||
remoteConfig = LHCAN.findConfbyName(topic+pfxlen,&remoteID);
|
||||
if (remoteConfig)
|
||||
{
|
||||
while(*(topic+pfxlen) && *(topic+pfxlen)!='/') pfxlen++; //skip controller name
|
||||
if (*(topic+pfxlen)=='/') pfxlen++;
|
||||
debugSerial<<F("MQTT: remote command Item:")<<topic+pfxlen<<endl;
|
||||
strncpy(savedTopic,topic,sizeof(savedTopic)-1); //Save topic to delete after exec
|
||||
}
|
||||
else pfxlen=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!pfxlen) {
|
||||
debugSerial<<F("Skipping..")<<endl;
|
||||
// debugSerial<<F("Skipping..")<<endl;
|
||||
return;// -3;
|
||||
}
|
||||
|
||||
@@ -473,12 +486,15 @@ else
|
||||
// debugSerial<<itemName<<endl;
|
||||
if(!strcmp_P(itemName,CMDTOPIC_P) && payload && (strlen((char*) payload)>1)) {
|
||||
mqttClient.deleteTopic(topic);
|
||||
cmd_parse((char *)payload);
|
||||
if (forLocal || forBcast) cmd_parse ((char *)payload);
|
||||
//TODO implement for remote
|
||||
return;// -4;
|
||||
}
|
||||
//if (itemName[0]=='$') return;// -6; //Skipping homie stuff
|
||||
if (strrchr(topic,'$')) return;
|
||||
|
||||
|
||||
/*
|
||||
Item item(itemName);
|
||||
if (item.isValid() && (item.Ctrl((char *)payload)>0) && savedTopic[0] && lanStatus != RETAINING_COLLECTING)
|
||||
|
||||
@@ -487,7 +503,37 @@ else
|
||||
debugSerial<<F("MQTT: Complete. Remove topic ")<<savedTopic<<endl;
|
||||
mqttClient.deleteTopic(savedTopic);
|
||||
}
|
||||
*/
|
||||
|
||||
bool succeeded = false;
|
||||
|
||||
if (forLocal || forBcast)
|
||||
{
|
||||
Item item(itemName);
|
||||
if (item.isValid()) //Local item
|
||||
{
|
||||
if (item.Ctrl((char *)payload)>0) succeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CANDRV
|
||||
if (remoteConfig)
|
||||
{
|
||||
aJsonObject * remoteItems = aJson.getObjectItem(remoteConfig,"items");
|
||||
if (remoteItems)
|
||||
{
|
||||
Item remoteItem(itemName,remoteItems);
|
||||
if (remoteItem.Ctrl((char *)payload,NULL,remoteID)>0) succeeded = true;
|
||||
}
|
||||
}
|
||||
/// TODO bcast - scan CAN
|
||||
#endif
|
||||
|
||||
if (succeeded && savedTopic[0] && lanStatus != RETAINING_COLLECTING)
|
||||
{
|
||||
debugSerial<<F("MQTT: Complete. Remove topic ")<<savedTopic<<endl;
|
||||
mqttClient.deleteTopic(savedTopic);
|
||||
}
|
||||
return;// -7;
|
||||
}
|
||||
|
||||
@@ -714,11 +760,16 @@ lan_status lanLoop() {
|
||||
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
|
||||
mqttClient.unsubscribe(buf);
|
||||
|
||||
#ifdef CANDRV
|
||||
setTopic(buf,sizeof(buf),T_ROOT);
|
||||
LHCAN.subscribeTopics(buf,sizeof(buf));
|
||||
#endif
|
||||
|
||||
onMQTTConnect();
|
||||
|
||||
#ifdef CRYPT
|
||||
//setTopic(buf,sizeof(buf),T_OUT);
|
||||
strncpy(buf, "+/+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
||||
setTopic(buf,sizeof(buf),T_ROOT);
|
||||
strncat(buf, "+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
||||
mqttClient.subscribe(buf);
|
||||
#endif
|
||||
|
||||
@@ -1385,8 +1436,8 @@ return 200;
|
||||
}
|
||||
#endif
|
||||
|
||||
void applyConfig() {
|
||||
if (!root || configLocked) return;
|
||||
bool applyConfig() {
|
||||
if (!root || configLocked) return false;
|
||||
configLocked++;
|
||||
infoSerial<<F("Applying config")<<endl;
|
||||
items = aJson.getObjectItem(root, "items");
|
||||
@@ -1532,6 +1583,7 @@ lanStatus=IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER; ///change
|
||||
if (lanStatus == OPERATION_NO_MQTT) lanStatus=IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
|
||||
|
||||
configLocked--;
|
||||
return configLoaded;
|
||||
}
|
||||
|
||||
void printConfigSummary() {
|
||||
@@ -1593,8 +1645,9 @@ int loadConfigFromEEPROM()
|
||||
|
||||
if (sysConfStream.peek() == '{') {
|
||||
debugSerial<<F("JSON detected")<<endl;
|
||||
if (root) cleanConf(1);
|
||||
|
||||
aJsonStream as = aJsonStream(&sysConfStream);
|
||||
cleanConf(false);
|
||||
root = aJson.parse(&as);
|
||||
sysConfStream.close();
|
||||
if (!root) {
|
||||
@@ -1605,6 +1658,7 @@ int loadConfigFromEEPROM()
|
||||
return 0;
|
||||
}
|
||||
infoSerial<<F("Loaded from EEPROM")<<endl;
|
||||
// debugSerial.print(aJson.print(root));
|
||||
configLocked--;
|
||||
applyConfig();
|
||||
sysConf.loadETAG();
|
||||
@@ -1895,7 +1949,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
infoSerial<<F("got Config\n"); delay(500);
|
||||
aJsonFileStream as = aJsonFileStream(configStream);
|
||||
noInterrupts();
|
||||
if (!cleanConf(true))
|
||||
if (!cleanConf(0))
|
||||
{
|
||||
errorSerial<<F("Get aborted")<<endl;
|
||||
hclient.closeStream(configStream);
|
||||
@@ -1972,7 +2026,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
if (responseStatusCode == 200) {
|
||||
aJsonStream socketStream = aJsonStream(&htclient);
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
if (!cleanConf(true))
|
||||
if (!cleanConf(0))
|
||||
{
|
||||
errorSerial<<F("Get aborted")<<endl;
|
||||
htclient.stop();
|
||||
@@ -2051,7 +2105,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
sysConf.setETAG(httpClient.header("ETag"));
|
||||
//String response = httpClient.getString();
|
||||
//debugSerial<<response;
|
||||
if (!cleanConf(true))
|
||||
if (!cleanConf(0))
|
||||
{
|
||||
errorSerial<<F("Get aborted")<<endl;
|
||||
httpClient.end();
|
||||
@@ -2458,10 +2512,14 @@ WiFi.onEvent(WiFiEvent);
|
||||
#endif
|
||||
|
||||
#endif //NOIP
|
||||
loadConfigFromEEPROM();
|
||||
|
||||
#ifdef CANDRV
|
||||
LHCAN.begin();
|
||||
#endif
|
||||
|
||||
loadConfigFromEEPROM();
|
||||
|
||||
#ifdef CANDRV
|
||||
LHCAN.lookupMAC();
|
||||
#endif
|
||||
}
|
||||
@@ -2659,6 +2717,18 @@ infoSerial<<F("\n(+)CAN");
|
||||
#else
|
||||
infoSerial<<F("\n(-)CAN");
|
||||
#endif
|
||||
|
||||
#ifdef PULSEPIN12
|
||||
infoSerial<<F("\n(+)PULSE on PIN12");
|
||||
#else
|
||||
infoSerial<<F("\n(-)PULSE on PIN12");
|
||||
#endif
|
||||
|
||||
#ifdef CRYPT
|
||||
infoSerial<<F("\n(+)CRYPT");
|
||||
#else
|
||||
infoSerial<<F("\n(-)CRYPT");
|
||||
#endif
|
||||
//#ifdef IPMODBUS
|
||||
//infoSerial<<F("\n(+)IPMODBUS");
|
||||
//#endif
|
||||
@@ -2733,7 +2803,6 @@ LHCAN.upTime(ut);
|
||||
#endif
|
||||
}
|
||||
|
||||
//#if not defined (NOIP)
|
||||
void setupMacAddress() {
|
||||
//Check MAC, stored in NVRAM
|
||||
|
||||
@@ -2765,12 +2834,7 @@ if (!sysConf.getMAC()) {
|
||||
#endif
|
||||
}
|
||||
printMACAddress();
|
||||
|
||||
#ifdef CANDRV
|
||||
// LHCAN.lookupMAC();
|
||||
#endif
|
||||
}
|
||||
//#endif //NOIP
|
||||
|
||||
void setupCmdArduino() {
|
||||
//cmdInit(uint32_t(SERIAL_BAUD));
|
||||
|
||||
@@ -268,7 +268,7 @@ int cmdFunctionHelp(int arg_cnt, char **args);
|
||||
|
||||
int cmdFunctionKill(int arg_cnt, char **args);
|
||||
|
||||
void applyConfig();
|
||||
bool applyConfig();
|
||||
|
||||
int cmdFunctionLoad(int arg_cnt, char **args);
|
||||
|
||||
@@ -283,6 +283,8 @@ int cmdFunctionGet(int arg_cnt, char **args);
|
||||
int cmdFunctionLoglevel(int arg_cnt, char **args);
|
||||
|
||||
void printBool(bool arg);
|
||||
|
||||
int cmdFunctionSave(int arg_cnt, char **args);
|
||||
/*
|
||||
void saveFlash(short n, char *str);
|
||||
|
||||
@@ -333,7 +335,7 @@ bool disabledDisconnected(const aJsonObject *thermoExtensionArray, int thermoLat
|
||||
|
||||
void resetHard();
|
||||
|
||||
bool cleanConf(bool wait);
|
||||
bool cleanConf(short locksAlowed=0);
|
||||
|
||||
void printCurentLanConfig();
|
||||
|
||||
|
||||
@@ -303,11 +303,12 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
switch (defMappingObj->type)
|
||||
{
|
||||
case aJson_Int: //register/coil/.. number
|
||||
traceSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
|
||||
traceSerial<<F("MBUSD: Searching reg#")<<defMappingObj->valueint<<endl;
|
||||
if ((defMappingObj->valueint>= registerFrom) && (defMappingObj->valueint<=registerTo))
|
||||
{
|
||||
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||
executeWithoutCheck=true;
|
||||
debugSerial<<"MBUSD: recurrent check res: "<<"SRO:"<<submitRecurrentOut<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -410,36 +411,59 @@ 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(markObj,"@S");
|
||||
if (lastMeasured)
|
||||
|
||||
bool storeLastValue = true;
|
||||
if (doExecution)
|
||||
{
|
||||
if (lastMeasured->type == aJson_Int)
|
||||
{
|
||||
if (lastMeasured->valueint == param)
|
||||
*submitParam=false; //supress repeating execution for same val
|
||||
else
|
||||
{
|
||||
lastMeasured->valueint=param;
|
||||
traceSerial<<"MBUS: Stored "<<param<<" to @S of "<<paramObj->name<<endl;
|
||||
lastMeasured->subtype&=~MB_VALUE_OUTDATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else //No container to store value yet
|
||||
{
|
||||
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
||||
aJson.addNumberToObject(markObj, "@S", (long) param);
|
||||
storeLastValue=false;
|
||||
// Check - if no action configured for object - not need to store last value - let requrent process do it
|
||||
|
||||
aJsonObject * i = execObj->child;
|
||||
while (i && !storeLastValue)
|
||||
{
|
||||
if (i->name && *i->name && (*i->name != '@')) storeLastValue = true;
|
||||
i=i->next;
|
||||
}
|
||||
}
|
||||
|
||||
aJsonObject * markObj = execObj;
|
||||
if (execObj->type == aJson_Array)
|
||||
{
|
||||
markObj = execObj->child;
|
||||
storeLastValue = true;
|
||||
}
|
||||
|
||||
if (storeLastValue)
|
||||
{
|
||||
//Retrive previous data
|
||||
aJsonObject *lastMeasured = aJson.getObjectItem(markObj,"@S");
|
||||
if (lastMeasured)
|
||||
{
|
||||
if (lastMeasured->type == aJson_Int)
|
||||
{
|
||||
if (lastMeasured->valueint == param)
|
||||
*submitParam=false; //supress repeating execution for same val
|
||||
else
|
||||
{
|
||||
lastMeasured->valueint=param;
|
||||
traceSerial<<"MBUS: Stored "<<param<<" to @S of "<<paramObj->name<<endl;
|
||||
lastMeasured->subtype&=~MB_VALUE_OUTDATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else //No container to store value yet
|
||||
{
|
||||
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
||||
aJson.addNumberToObject(markObj, "@S", (long) param);
|
||||
}
|
||||
}
|
||||
|
||||
if (executeWithoutCheck)
|
||||
{
|
||||
|
||||
if (doExecution && (submitRecurrentOut || *submitParam))
|
||||
{
|
||||
//debugSerial<<F("MBUS: exec ");mappedParam.debugOut();
|
||||
executeCommand(execObj, -1, mappedParam);
|
||||
*submitParam=true; //if requrrent check has submit smth - report it.
|
||||
}
|
||||
@@ -447,7 +471,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
return mappedParam;
|
||||
}
|
||||
|
||||
if (*submitParam)
|
||||
if (*submitParam && doExecution)
|
||||
{
|
||||
// Compare with last submitted val (if @V NOT marked as NULL in config)
|
||||
aJsonObject *settedValue = aJson.getObjectItem(markObj,"@V");
|
||||
@@ -458,7 +482,11 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
}
|
||||
else
|
||||
{
|
||||
if (doExecution) executeCommand(execObj, -1, mappedParam);
|
||||
if (doExecution)
|
||||
{
|
||||
//debugSerial<<F("MBUS: exec ");mappedParam.debugOut();
|
||||
executeCommand(execObj, -1, mappedParam);
|
||||
}
|
||||
// if param updated by device and no new value queued to send - update @V to avoid "Ignored - equal with setted val"
|
||||
if (settedValue && !(execObj->subtype & MB_NEED_SEND))
|
||||
settedValue->valueint=param;
|
||||
@@ -556,13 +584,14 @@ int out_Modbus::sendModbus(char * paramName, aJsonObject * outValue)
|
||||
if (prefetchObj && (prefetchObj->type == aJson_Boolean) && prefetchObj->valuebool)
|
||||
{
|
||||
int modbusRegType = (outValue->subtype == PAR_COIL) ? MODBUS_COIL_REG_TYPE:MODBUS_HOLDING_REG_TYPE;
|
||||
debugSerial<<F("\nMBUS: prefetching ")<<paramName<<F(" #") <<regObj->valueint << " type:" << modbusRegType << " ";
|
||||
debugSerial<<F(" prefetch ")<<paramName<<F(" #") <<regObj->valueint << " type:" << modbusRegType << " ";
|
||||
|
||||
/// to prevent CORRUPTIOIN if using same buffer
|
||||
uint16_t localBuffer;
|
||||
node.setResponseBuffer(&localBuffer,1);
|
||||
|
||||
bool successRead = readModbus(regObj->valueint,modbusRegType,1);
|
||||
mbusSlenceTimer = millisNZ();
|
||||
|
||||
|
||||
if (successRead)
|
||||
@@ -607,6 +636,13 @@ if (prefetchObj && (prefetchObj->type == aJson_Boolean) && prefetchObj->valueboo
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outValue->valueint == localBuffer)
|
||||
{
|
||||
debugSerial << F("MBUS:")<<paramName<< F("=")<<localBuffer<<F(": equal targert.")<<endl;
|
||||
node.setDefaultResponseBuffer();
|
||||
return -4;
|
||||
}
|
||||
|
||||
debugSerial << F("MBUS:")<<paramName<< F(" val not changed. Continue")<<endl;
|
||||
}
|
||||
}
|
||||
@@ -664,7 +700,7 @@ int out_Modbus::Poll(short cause)
|
||||
if (cause==POLLING_SLOW) return 0;
|
||||
bool lineInitialized = false;
|
||||
|
||||
if (modbusBusy || (Status() != CST_INITIALIZED) || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100))) return 0;
|
||||
if (modbusBusy || (Status() != CST_INITIALIZED) || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),200))) return 0;
|
||||
|
||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
@@ -692,18 +728,23 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
|
||||
int sendRes;
|
||||
int savedValue;
|
||||
bool needResend;
|
||||
do
|
||||
{
|
||||
savedValue = outValue->valueint;
|
||||
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
|
||||
sendRes = sendModbus(execObj->name,outValue);
|
||||
needResend = (savedValue != outValue->valueint);
|
||||
while(needResend && mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),200)) modbusIdle();
|
||||
}
|
||||
while (savedValue != outValue->valueint); //repeat sending if target value changed while we're waited for mbus responce
|
||||
while (needResend); //repeat sending if target value changed while we're waited for mbus responce
|
||||
|
||||
switch (sendRes)
|
||||
{
|
||||
case 1: //success
|
||||
execObj->subtype&=~ MB_NEED_SEND;
|
||||
case -4: //equal tatget
|
||||
//execObj->subtype&=~ MB_NEED_SEND;
|
||||
execObj->subtype = 0;
|
||||
onceSendOk=true;
|
||||
///return 1; //relax
|
||||
break;
|
||||
@@ -716,7 +757,8 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
case -3:
|
||||
errorSerial<<F("MBUS: param ")<<execObj->name<<F(" sending cancelled")<<endl;
|
||||
//outValue->valueint=
|
||||
execObj->subtype&=~ MB_NEED_SEND;
|
||||
//execObj->subtype&=~ MB_NEED_SEND;
|
||||
execObj->subtype = 0;
|
||||
break;
|
||||
default: //param not found
|
||||
errorSerial<<F("MBUS: param ")<<execObj->name<<F(" not found")<<endl;
|
||||
@@ -730,7 +772,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
}
|
||||
|
||||
|
||||
if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenceTimer || isTimeOver(mbusSlenceTimer,millis(),100)))
|
||||
if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenceTimer || isTimeOver(mbusSlenceTimer,millis(),200)))
|
||||
{
|
||||
|
||||
// Clean_up FLAG_SEND_ERROR flag
|
||||
|
||||
@@ -531,9 +531,12 @@ if (_l2 && _l2->type == aJson_String) strncat(buf,_l2->valuestring,buflen);
|
||||
strncat_P(buf,inTopic,buflen); /////
|
||||
break;
|
||||
}
|
||||
strncat(buf,"/",buflen);
|
||||
if (suffix) strncat(buf,suffix,buflen);
|
||||
|
||||
if (tt!=T_ROOT)
|
||||
{
|
||||
strncat(buf,"/",buflen);
|
||||
if (suffix) strncat(buf,suffix,buflen);
|
||||
}
|
||||
return buf;
|
||||
|
||||
}
|
||||
@@ -974,7 +977,19 @@ return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef CANDRV
|
||||
uint16_t getCRC(aJsonObject * in)
|
||||
{
|
||||
if (!in) return 0;
|
||||
CRCStream crcStream;
|
||||
aJsonStream aJsonCrcStream = aJsonStream(&crcStream);
|
||||
//debugSerial<<"CRC: in";
|
||||
//debugSerial.print(aJson.print(in));
|
||||
aJson.print(in,&aJsonCrcStream,false);
|
||||
//debugSerial<<"\nCRC:"<<crcStream.getCRC16();
|
||||
return crcStream.getCRC16();
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma message(VAR_NAME_VALUE(debugSerial))
|
||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||
|
||||
@@ -38,6 +38,7 @@ using namespace ios;
|
||||
#endif
|
||||
|
||||
enum topicType {
|
||||
T_ROOT = 4,
|
||||
T_DEV = 1,
|
||||
T_BCST= 2,
|
||||
T_OUT = 3
|
||||
@@ -80,4 +81,26 @@ int str2regSize(char * str);
|
||||
bool checkToken(char * token, char * data);
|
||||
bool isProtectedPin(short pin);
|
||||
bool i2cReset();
|
||||
uint16_t getCRC(aJsonObject * in);
|
||||
|
||||
#ifdef CANDRV
|
||||
#include "util/crc16_.h"
|
||||
class CRCStream : public Stream
|
||||
{
|
||||
public:
|
||||
CRCStream() : CRC16(0xFFFF){}
|
||||
uint16_t CRC16;
|
||||
uint16_t getCRC16() {return CRC16;}
|
||||
|
||||
// Stream methods
|
||||
virtual int available(){return 0;};
|
||||
virtual int read(){return 0;};
|
||||
virtual int peek(){return 0;};
|
||||
|
||||
virtual void flush(){};
|
||||
// Print methods
|
||||
virtual size_t write(uint8_t c) {CRC16 = crc16_update(CRC16, c);return 1;};
|
||||
virtual int availableForWrite(){return 1;};
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -359,6 +359,8 @@ lib_ignore =
|
||||
ModbusMaster
|
||||
ClosedCube HDC1080
|
||||
SparkFun CCS811 Arduino Library
|
||||
;ArduinoOTA
|
||||
ArduinoMDNS
|
||||
;Adafruit BusIO
|
||||
;Adafruit MCP23017 Arduino Library
|
||||
;Adafruit Unified Sensor
|
||||
@@ -388,7 +390,7 @@ lib_deps =
|
||||
Adafruit MCP23017 Arduino Library
|
||||
Adafruit BusIO
|
||||
br3ttb/PID@^1.2.1
|
||||
ArduinoMDNS
|
||||
;ArduinoMDNS
|
||||
;https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||
|
||||
monitor_speed = 115200
|
||||
@@ -820,7 +822,6 @@ lib_ignore =
|
||||
DallasTemperature
|
||||
Adafruit Unified Sensor
|
||||
DS2482_OneWire
|
||||
ModbusMaster
|
||||
Syslog
|
||||
;EEPROM
|
||||
ClosedCube HDC1080
|
||||
@@ -843,6 +844,7 @@ lib_deps =
|
||||
br3ttb/PID@^1.2.1
|
||||
ArduinoMDNS
|
||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
@@ -888,7 +890,6 @@ lib_ignore =
|
||||
DallasTemperature
|
||||
Adafruit Unified Sensor
|
||||
DS2482_OneWire
|
||||
ModbusMaster
|
||||
Syslog
|
||||
NRFFlashStorage
|
||||
ClosedCube HDC1080
|
||||
@@ -911,7 +912,8 @@ lib_deps =
|
||||
br3ttb/PID@^1.2.1
|
||||
ArduinoMDNS
|
||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||
;https://github.com/anklimov/ModbusMaster
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
@@ -957,7 +959,6 @@ lib_ignore =
|
||||
DallasTemperature
|
||||
Adafruit Unified Sensor
|
||||
DS2482_OneWire
|
||||
ModbusMaster
|
||||
Syslog
|
||||
NRFFlashStorage
|
||||
ClosedCube HDC1080
|
||||
@@ -980,7 +981,7 @@ lib_deps =
|
||||
br3ttb/PID@^1.2.1
|
||||
; ArduinoMDNS
|
||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||
;https://github.com/anklimov/ModbusMaster
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
pazi88/STM32_CAN
|
||||
ericksimoes/Ultrasonic
|
||||
|
||||
|
||||
Reference in New Issue
Block a user