mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 03:39:49 +03:00
NO-IP devices persistence
STM Flash cfg fix CAN GROUP chan fix CRC16 fix
This commit is contained in:
@@ -156,12 +156,21 @@ return res;
|
||||
|
||||
bool canDriver::begin()
|
||||
{
|
||||
if (!root) return false;
|
||||
canConfigObj = aJson.getObjectItem(root, "can");
|
||||
if (!canConfigObj) return false;
|
||||
canRemoteConfigObj= aJson.getObjectItem(canConfigObj, "conf");
|
||||
if (root)
|
||||
{
|
||||
canConfigObj = aJson.getObjectItem(root, "can");
|
||||
if (canConfigObj)
|
||||
{
|
||||
canRemoteConfigObj= aJson.getObjectItem(canConfigObj, "conf");
|
||||
controllerId = getMyId();
|
||||
}
|
||||
confCRC=getCRC(root);
|
||||
}
|
||||
|
||||
|
||||
controllerId = getMyId();
|
||||
#ifndef NOIP
|
||||
if (!canConfigObj) return false;
|
||||
#endif
|
||||
|
||||
if (!ready) // not reInitialization
|
||||
{
|
||||
@@ -314,7 +323,7 @@ switch (state)
|
||||
if (CANConfStream.peek() == '{') {
|
||||
debugSerial<<F("CAN: JSON detected")<<endl;
|
||||
aJsonStream as = aJsonStream(&CANConfStream);
|
||||
cleanConf(false);
|
||||
cleanConf(1);
|
||||
root = aJson.parse(&as);
|
||||
CANConfStream.close();
|
||||
if (!root) {
|
||||
@@ -327,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 ;
|
||||
@@ -446,10 +457,12 @@ if (id.status){
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -465,7 +478,7 @@ if (id.status){
|
||||
case canState::MACLookup:
|
||||
if ((id.payloadType == payloadType::lookupMAC))
|
||||
{
|
||||
if (canConfigObj && (id.subjId == getCRC(canConfigObj))) ///?
|
||||
if (root && (id.subjId == confCRC)) ///?
|
||||
{
|
||||
infoSerial << (F("Valid config already onboard")) << endl;
|
||||
state = canState::Idle;
|
||||
@@ -661,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;canConfigObj=NULL;canRemoteConfigObj=NULL;};
|
||||
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 );
|
||||
@@ -143,6 +143,7 @@ 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -159,10 +159,21 @@ void Item::Parse() {
|
||||
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;
|
||||
/*
|
||||
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);
|
||||
*/
|
||||
|
||||
aJsonObject * itemTypeObj = itemArr->child;
|
||||
if (itemTypeObj) itemArg = itemTypeObj->next;
|
||||
if (itemArg) itemVal = itemArg->next;
|
||||
if (itemVal) itemExt = itemVal->next;
|
||||
|
||||
itemType = replaceTypeToInt (itemTypeObj);
|
||||
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
#ifndef PWM_DISABLE
|
||||
@@ -861,7 +872,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
|
||||
@@ -869,8 +882,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);
|
||||
@@ -888,6 +902,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--;
|
||||
|
||||
@@ -177,11 +177,11 @@ 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 (configLocked>locksAlowed)
|
||||
{
|
||||
errorSerial<<F("Can not clean - locked")<<endl;
|
||||
return false;
|
||||
@@ -436,6 +436,7 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
char * itemName = NULL;
|
||||
char savedTopic[MQTT_TOPIC_LENGTH] = "";
|
||||
bool forLocal=false;
|
||||
bool forBcast=false;
|
||||
aJsonObject * remoteConfig = NULL;
|
||||
int remoteID=0;
|
||||
|
||||
@@ -461,15 +462,29 @@ if (lanStatus == RETAINING_COLLECTING)
|
||||
}
|
||||
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); //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;
|
||||
|
||||
//if (pfxlen) forLocal=true;
|
||||
|
||||
#ifdef CANDRV
|
||||
else //Nor local or bcst name, try can names
|
||||
// else //Nor local or bcst name, try can names
|
||||
if (!forLocal && !forBcast)
|
||||
{
|
||||
pfxlen=inTopic(topic,T_ROOT); //check root
|
||||
if (pfxlen)
|
||||
@@ -497,7 +512,7 @@ else
|
||||
// debugSerial<<itemName<<endl;
|
||||
if(!strcmp_P(itemName,CMDTOPIC_P) && payload && (strlen((char*) payload)>1)) {
|
||||
mqttClient.deleteTopic(topic);
|
||||
if (forLocal)((char *)payload);
|
||||
if (forLocal || forBcast)((char *)payload);
|
||||
//TODO implement for remote
|
||||
return;// -4;
|
||||
}
|
||||
@@ -518,7 +533,7 @@ else
|
||||
|
||||
bool succeeded = false;
|
||||
|
||||
if (forLocal)
|
||||
if (forLocal || forBcast)
|
||||
{
|
||||
Item item(itemName);
|
||||
if (item.isValid()) //Local item
|
||||
@@ -536,7 +551,8 @@ else
|
||||
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)
|
||||
@@ -1446,8 +1462,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");
|
||||
@@ -1593,6 +1609,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() {
|
||||
@@ -1655,7 +1672,7 @@ int loadConfigFromEEPROM()
|
||||
if (sysConfStream.peek() == '{') {
|
||||
debugSerial<<F("JSON detected")<<endl;
|
||||
aJsonStream as = aJsonStream(&sysConfStream);
|
||||
cleanConf(false);
|
||||
cleanConf(0); ///WTF!
|
||||
root = aJson.parse(&as);
|
||||
sysConfStream.close();
|
||||
if (!root) {
|
||||
@@ -1665,7 +1682,8 @@ int loadConfigFromEEPROM()
|
||||
configLocked--;
|
||||
return 0;
|
||||
}
|
||||
infoSerial<<F("Loaded from EEPROM")<<endl;
|
||||
infoSerial<<F("Loaded from EEPROM")<<endl;
|
||||
// debugSerial.print(aJson.print(root));
|
||||
configLocked--;
|
||||
applyConfig();
|
||||
sysConf.loadETAG();
|
||||
@@ -2518,11 +2536,15 @@ WiFi.onEvent(WiFiEvent);
|
||||
infoSerial<<QUOTE(W5500_CS_PIN)<<endl;
|
||||
#endif
|
||||
|
||||
#endif //NOIP
|
||||
loadConfigFromEEPROM();
|
||||
#endif //NOIP
|
||||
|
||||
#ifdef CANDRV
|
||||
LHCAN.begin();
|
||||
#endif
|
||||
|
||||
loadConfigFromEEPROM();
|
||||
|
||||
#ifdef CANDRV
|
||||
LHCAN.lookupMAC();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -482,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;
|
||||
@@ -696,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)
|
||||
@@ -731,7 +735,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
|
||||
sendRes = sendModbus(execObj->name,outValue);
|
||||
needResend = (savedValue != outValue->valueint);
|
||||
while(needResend && mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100)) modbusIdle();
|
||||
while(needResend && mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),200)) modbusIdle();
|
||||
}
|
||||
while (needResend); //repeat sending if target value changed while we're waited for mbus responce
|
||||
|
||||
@@ -768,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
|
||||
|
||||
@@ -983,7 +983,10 @@ uint16_t getCRC(aJsonObject * in)
|
||||
if (!in) return 0;
|
||||
CRCStream crcStream;
|
||||
aJsonStream aJsonCrcStream = aJsonStream(&crcStream);
|
||||
aJson.print(in,&aJsonCrcStream);
|
||||
debugSerial<<"CRC: in";
|
||||
debugSerial.print(aJson.print(in));
|
||||
aJson.print(in,&aJsonCrcStream,false);
|
||||
debugSerial<<"\nCRC:"<<crcStream.getCRC16();
|
||||
return crcStream.getCRC16();
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ bool checkToken(char * token, char * data);
|
||||
bool isProtectedPin(short pin);
|
||||
bool i2cReset();
|
||||
uint16_t getCRC(aJsonObject * in);
|
||||
|
||||
|
||||
#include "util/crc16_.h"
|
||||
class CRCStream : public Stream
|
||||
{
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
|
||||
virtual void flush(){};
|
||||
// Print methods
|
||||
virtual size_t write(uint8_t c) {CRC16 = crc16_update(CRC16, c);};
|
||||
virtual size_t write(uint8_t c) {CRC16 = crc16_update(CRC16, c);return 1;};
|
||||
virtual int availableForWrite(){return 1;};
|
||||
|
||||
};
|
||||
|
||||
@@ -820,7 +820,6 @@ lib_ignore =
|
||||
DallasTemperature
|
||||
Adafruit Unified Sensor
|
||||
DS2482_OneWire
|
||||
ModbusMaster
|
||||
Syslog
|
||||
;EEPROM
|
||||
ClosedCube HDC1080
|
||||
@@ -843,6 +842,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 +888,6 @@ lib_ignore =
|
||||
DallasTemperature
|
||||
Adafruit Unified Sensor
|
||||
DS2482_OneWire
|
||||
ModbusMaster
|
||||
Syslog
|
||||
NRFFlashStorage
|
||||
ClosedCube HDC1080
|
||||
@@ -912,6 +911,7 @@ lib_deps =
|
||||
ArduinoMDNS
|
||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||
;https://github.com/anklimov/ModbusMaster
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
|
||||
monitor_speed = 115200
|
||||
|
||||
@@ -957,7 +957,6 @@ lib_ignore =
|
||||
DallasTemperature
|
||||
Adafruit Unified Sensor
|
||||
DS2482_OneWire
|
||||
ModbusMaster
|
||||
Syslog
|
||||
NRFFlashStorage
|
||||
ClosedCube HDC1080
|
||||
@@ -980,7 +979,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