mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Complex MBUS mapping, PID fix
This commit is contained in:
@@ -1451,6 +1451,8 @@ int Item::SendStatus(int sendFlags) {
|
||||
case CMD_COOL:
|
||||
case CMD_DRY:
|
||||
case CMD_FAN:
|
||||
case CMD_ENABLE:
|
||||
case CMD_DISABLE:
|
||||
strcpy_P(cmdstr, ON_P);
|
||||
break;
|
||||
case CMD_OFF:
|
||||
@@ -1571,6 +1573,12 @@ int Item::SendStatus(int sendFlags) {
|
||||
case CMD_FAN:
|
||||
strcpy_P(cmdstr, FAN_ONLY_P);
|
||||
break;
|
||||
case CMD_ENABLE:
|
||||
strcpy_P(cmdstr, ENABLE_P);
|
||||
break;
|
||||
case CMD_DISABLE:
|
||||
strcpy_P(cmdstr, DISABLE_P);
|
||||
break;
|
||||
case CMD_ON:
|
||||
case CMD_XON:
|
||||
if (itemType == CH_THERMO) strcpy_P(cmdstr, AUTO_P);
|
||||
|
||||
@@ -1242,10 +1242,10 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
|
||||
case aJson_Array:
|
||||
{
|
||||
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, no reverse mapping, skipping
|
||||
if (i && i->type==aJson_Int)
|
||||
{
|
||||
matchedCmd = i;
|
||||
//matchedCmd = i;
|
||||
i=i->next;
|
||||
}
|
||||
|
||||
@@ -1301,6 +1301,7 @@ if (valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMappi
|
||||
int diff = ((b-a)/(d-c))/2;
|
||||
return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255));
|
||||
}
|
||||
if (valMapping && valMapping->type == aJson_NULL) return itemCmd();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,10 +231,15 @@ return (result == node.ku8MBSuccess);
|
||||
|
||||
|
||||
|
||||
int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uint8_t regType, uint16_t registerFrom, uint16_t registerTo, bool doExecution, bool * submitParam)
|
||||
{
|
||||
aJsonObject * paramObj = store->parameters->child;
|
||||
bool is8bit = false;
|
||||
|
||||
bool tmpSubmitParam;
|
||||
if (!submitParam) submitParam=&tmpSubmitParam;
|
||||
*submitParam=true;
|
||||
|
||||
//bool is8bit = false;
|
||||
while (paramObj)
|
||||
{
|
||||
aJsonObject *regObj=NULL;
|
||||
@@ -248,11 +253,14 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
{
|
||||
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
|
||||
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
||||
aJsonObject *idObj = aJson.getObjectItem(paramObj, "id");
|
||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
uint16_t data = node.getResponseBuffer(posInBuffer);
|
||||
int8_t regType = PAR_I16;
|
||||
uint32_t param =0;
|
||||
itemCmd mappedParam;
|
||||
bool executeWithoutCheck=false; //Afler recurrent check, all dublicatess and suppressing checked by recurrent
|
||||
bool submitRecurrentOut = false; //false if recurrent check find duplicates
|
||||
char buf[16];
|
||||
|
||||
//bool isSigned=false;
|
||||
@@ -308,15 +316,47 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
|
||||
{
|
||||
mappedParam=mappedParam.doReverseMapping(mapObj);
|
||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
if (!mappedParam.isCommand() && !mappedParam.isValue()) //Not mapped
|
||||
{
|
||||
aJsonObject *nextRegObj = NULL;
|
||||
int registerType = 0;
|
||||
|
||||
nextRegObj = aJson.getObjectItem(paramObj, "nextreg");
|
||||
if (nextRegObj) registerType=MODBUS_HOLDING_REG_TYPE;
|
||||
else
|
||||
{
|
||||
nextRegObj = aJson.getObjectItem(paramObj, "nextir");
|
||||
if (nextRegObj) registerType=MODBUS_INPUT_REG_TYPE;
|
||||
}
|
||||
|
||||
if (registerType && (nextRegObj->type) ==aJson_Int && (nextRegObj->valueint>= registerFrom) && (nextRegObj->valueint<=registerTo))
|
||||
{
|
||||
debugSerial<<F("Recurrent searching nextreg")<<endl;
|
||||
mappedParam = findRegister(nextRegObj->valueint,nextRegObj->valueint-registerFrom,registerType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||
executeWithoutCheck=true;
|
||||
}
|
||||
else errorSerial<<F("nextreg out of range")<<endl;
|
||||
}
|
||||
else
|
||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
} //mapping
|
||||
|
||||
if (doExecution && idObj && idObj->type==aJson_Int)
|
||||
switch (idObj->valueint)
|
||||
{
|
||||
case S_CMD:
|
||||
mappedParam.saveItem(item,SEND_COMMAND);
|
||||
break;
|
||||
case S_SET:
|
||||
mappedParam.saveItem(item,SEND_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,paramObj->name);
|
||||
if (execObj)
|
||||
{
|
||||
bool submitParam=true;
|
||||
//Retrive previous data
|
||||
aJsonObject *lastMeasured = aJson.getObjectItem(execObj,"@S");
|
||||
if (lastMeasured)
|
||||
@@ -324,7 +364,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
if (lastMeasured->type == aJson_Int)
|
||||
{
|
||||
if (lastMeasured->valueint == param)
|
||||
submitParam=false; //supress repeating execution for same val
|
||||
*submitParam=false; //supress repeating execution for same val
|
||||
else lastMeasured->valueint=param;
|
||||
}
|
||||
}
|
||||
@@ -333,31 +373,39 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
||||
aJson.addNumberToObject(execObj, "@S", (long) param);
|
||||
}
|
||||
if (submitParam)
|
||||
|
||||
|
||||
if (executeWithoutCheck)
|
||||
{
|
||||
|
||||
if (doExecution && (submitRecurrentOut || *submitParam)) executeCommand(execObj, -1, mappedParam);
|
||||
return mappedParam;
|
||||
}
|
||||
|
||||
if (*submitParam)
|
||||
{
|
||||
//#ifdef MB_SUPPRESS_OUT_EQ_IN
|
||||
// Compare with last submitted val (if @V NOT marked as NULL in config)
|
||||
aJsonObject *settedValue = aJson.getObjectItem(execObj,"@V");
|
||||
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
|
||||
{
|
||||
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
||||
*submitParam=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
executeCommand(execObj, -1, mappedParam);
|
||||
if (doExecution) 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;
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is8bit) return 1;
|
||||
return mappedParam;
|
||||
}
|
||||
paramObj=paramObj->next;
|
||||
}
|
||||
return is8bit;
|
||||
return itemCmd();
|
||||
}
|
||||
|
||||
|
||||
@@ -376,7 +424,7 @@ return is8bit;
|
||||
//if (readModbus(registerNum,MODBUS_HOLDING_REG_TYPE,1))
|
||||
if (readModbus(registerNum,regType,1))
|
||||
{
|
||||
findRegister(registerNum,0,regType);
|
||||
findRegister(registerNum,0,regType,registerNum,registerNum);
|
||||
// data = node.getResponseBuffer(j);
|
||||
}
|
||||
}
|
||||
@@ -392,7 +440,7 @@ return is8bit;
|
||||
{ debugSerial<<endl;
|
||||
for(int i=registerFrom;i<=registerTo;i++)
|
||||
{
|
||||
findRegister(i,i-registerFrom,regType);
|
||||
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
|
||||
}
|
||||
//data = node.getResponseBuffer(j);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
protected:
|
||||
mbPersistent * store;
|
||||
bool getConfig();
|
||||
int findRegister(int registerNum, int posInBuffer, int regType);
|
||||
itemCmd findRegister(uint16_t registerNum, uint16_t posInBuffer, uint8_t regType, uint16_t registerFrom, uint16_t registerTo, bool doExecution = true, bool * submitParam = NULL);
|
||||
void pollModbus(aJsonObject * reg, int regType);
|
||||
void initLine();
|
||||
int sendModbus(char * paramName, int32_t value, uint8_t regType);
|
||||
|
||||
@@ -172,15 +172,20 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm
|
||||
{
|
||||
if(store->pid->Compute() )
|
||||
{
|
||||
int alarmVal;
|
||||
if (store->alarmArmed && (alarmVal=getAlarmVal()>=0)) store->output=alarmVal;
|
||||
float alarmVal;
|
||||
if (store->alarmArmed && ((alarmVal=getAlarmVal())>=0.)) store->output=alarmVal;
|
||||
debugSerial<<F("PID ")<<item->itemArr->name<<F(" set:")<<store->setpoint<<F(" in:")<<store->input<<(" out:") << store->output <<F(" P:")<<store->pid->GetKp() <<F(" I:")<<store->pid->GetKi() <<F(" D:")<<store->pid->GetKd();
|
||||
if (store->alarmArmed) debugSerial << F(" Alarm");
|
||||
debugSerial<<endl;
|
||||
|
||||
if ((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) && !store->alarmArmed)
|
||||
if (((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) || (item->getCmd() == CMD_ENABLE)) && !store->alarmArmed)
|
||||
{
|
||||
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
||||
if (item->getCmd() == CMD_ENABLE)
|
||||
{
|
||||
executeCommand(oCmd,-1,itemCmd().Cmd(CMD_ON));
|
||||
item->setCmd(CMD_VOID);
|
||||
}
|
||||
itemCmd value((float) (store->output));// * (100./255.)));
|
||||
value.setSuffix(S_SET);
|
||||
executeCommand(oCmd,-1,value);
|
||||
@@ -198,16 +203,16 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm
|
||||
return 1;//store->pollingInterval;
|
||||
};
|
||||
|
||||
int out_pid::getAlarmVal()
|
||||
float out_pid::getAlarmVal()
|
||||
{
|
||||
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
||||
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
||||
{
|
||||
errorSerial<<F("Invalid PID param array.")<<endl;
|
||||
return -1;
|
||||
return -1.;
|
||||
}
|
||||
|
||||
int outAlarm=0;
|
||||
float outAlarm=0.;
|
||||
double kP=0.;
|
||||
|
||||
bool alarmValDefined = false;
|
||||
@@ -232,13 +237,14 @@ int out_pid::getAlarmVal()
|
||||
if (param->type == aJson_Float) kP=param->valuefloat;
|
||||
else if (param->type == aJson_Int) kP=param->valueint;
|
||||
{
|
||||
if (kP<0)
|
||||
if (kP<0.)
|
||||
{
|
||||
if (!alarmValDefined) outAlarm = 0.;
|
||||
}
|
||||
else if (!alarmValDefined) outAlarm = 255.;
|
||||
}
|
||||
}
|
||||
debugSerial<<F("Alarm value: ")<<outAlarm<< " ";
|
||||
return outAlarm;
|
||||
}
|
||||
|
||||
@@ -250,7 +256,7 @@ if (!item || !item->itemArg) return;
|
||||
{
|
||||
float outAlarm=getAlarmVal();
|
||||
errorSerial<<item->itemArr->name<<F(" PID alarm. ")<<endl;
|
||||
if (outAlarm>=0)
|
||||
if (outAlarm>=0.)
|
||||
{
|
||||
errorSerial<<F("Set out to ")<<outAlarm<<endl;
|
||||
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
||||
@@ -339,16 +345,17 @@ case S_CMD:
|
||||
|
||||
executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
|
||||
case CMD_ENABLE:
|
||||
item->setCmd(CMD_ENABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
//executeCommand(oCmd,-1,value);
|
||||
executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
|
||||
case CMD_DISABLE:
|
||||
item->setCmd(CMD_DISABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
//executeCommand(oCmd,-1,value);
|
||||
executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
/*
|
||||
case CMD_OFF:
|
||||
@@ -361,11 +368,11 @@ case S_CMD:
|
||||
} */
|
||||
|
||||
default:
|
||||
debugSerial<<F("Unknown cmd ")<<cmd.getCmd()<<endl;
|
||||
debugSerial<<F("PID: Unknown cmd ")<<cmd.getCmd()<<endl;
|
||||
} //switch cmd
|
||||
}
|
||||
default:
|
||||
debugSerial<<F("Unknown suffix ")<<suffixCode<<endl;
|
||||
debugSerial<<F("PID: Unknown suffix ")<<suffixCode<<endl;
|
||||
} //switch suffix
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -112,6 +112,8 @@ const char HIGH_P[] PROGMEM = "HIGH";
|
||||
const char MED_P[] PROGMEM = "MEDIUM";
|
||||
const char LOW_P[] PROGMEM = "LOW";
|
||||
const char ERROR_P[] PROGMEM = "ERR";
|
||||
const char ENABLE_P[] PROGMEM = "ENABLE";
|
||||
const char DISABLE_P[] PROGMEM = "DISABLE";
|
||||
|
||||
|
||||
// SubTopics
|
||||
|
||||
Reference in New Issue
Block a user