mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
MBus channel module - write register implemented
This commit is contained in:
@@ -635,6 +635,33 @@ return (cmd.itemArgType==ST_HS || cmd.itemArgType==ST_HSV255 || cmd.itemArgType=
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long int itemCmd::getTens()
|
||||||
|
{
|
||||||
|
switch (cmd.itemArgType) {
|
||||||
|
|
||||||
|
case ST_INT32:
|
||||||
|
case ST_UINT32:
|
||||||
|
case ST_RGB:
|
||||||
|
case ST_RGBW:
|
||||||
|
|
||||||
|
return param.aslong*10;
|
||||||
|
case ST_PERCENTS255:
|
||||||
|
case ST_HSV255:
|
||||||
|
return param.v*10;
|
||||||
|
|
||||||
|
case ST_FLOAT:
|
||||||
|
case ST_FLOAT_CELSIUS:
|
||||||
|
case ST_FLOAT_FARENHEIT:
|
||||||
|
return param.asfloat*10.0;
|
||||||
|
case ST_TENS:
|
||||||
|
return param.aslong;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
long int itemCmd::getInt()
|
long int itemCmd::getInt()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ public:
|
|||||||
bool incrementS(int16_t);
|
bool incrementS(int16_t);
|
||||||
|
|
||||||
long int getInt();
|
long int getInt();
|
||||||
|
long int getTens();
|
||||||
float getFloat();
|
float getFloat();
|
||||||
char * getString();
|
char * getString();
|
||||||
long int getSingleInt();
|
long int getSingleInt();
|
||||||
|
|||||||
@@ -171,8 +171,6 @@ if (!store)
|
|||||||
store->timestamp=millisNZ();
|
store->timestamp=millisNZ();
|
||||||
if (getConfig())
|
if (getConfig())
|
||||||
{
|
{
|
||||||
//item->clearFlag(ACTION_NEEDED);
|
|
||||||
//item->clearFlag(ACTION_IN_PROCESS);
|
|
||||||
infoSerial<<F("Modbus config loaded ")<< item->itemArr->name<<endl;
|
infoSerial<<F("Modbus config loaded ")<< item->itemArr->name<<endl;
|
||||||
store->driverStatus = CST_INITIALIZED;
|
store->driverStatus = CST_INITIALIZED;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -285,7 +283,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
|||||||
|
|
||||||
case PAR_U8H:
|
case PAR_U8H:
|
||||||
//is8bit=true;
|
//is8bit=true;
|
||||||
param = data << 8;
|
param = (data & 0xFF00) >> 8;
|
||||||
mappedParam.Int((uint32_t)param);
|
mappedParam.Int((uint32_t)param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -371,12 +369,8 @@ return is8bit;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_Modbus::Poll(short cause)
|
void out_Modbus::initLine()
|
||||||
{
|
{
|
||||||
if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() == CST_INITIALIZED) && isTimeOver(store->timestamp,millis(),store->pollingInterval))
|
|
||||||
{
|
|
||||||
debugSerial<<F("Poll ")<< item->itemArr->name << endl;
|
|
||||||
modbusBusy=1;
|
|
||||||
//store->serialParam=(USARTClass::USARTModes) SERIAL_8N1;
|
//store->serialParam=(USARTClass::USARTModes) SERIAL_8N1;
|
||||||
#if defined (__SAM3X8E__)
|
#if defined (__SAM3X8E__)
|
||||||
modbusSerial.begin(store->baud, static_cast <USARTClass::USARTModes> (store->serialParam));
|
modbusSerial.begin(store->baud, static_cast <USARTClass::USARTModes> (store->serialParam));
|
||||||
@@ -391,11 +385,120 @@ if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() =
|
|||||||
#endif
|
#endif
|
||||||
debugSerial<< store->baud << F("---")<< store->serialParam<<endl;
|
debugSerial<< store->baud << F("---")<< store->serialParam<<endl;
|
||||||
node.begin(item->getArg(0), modbusSerial);
|
node.begin(item->getArg(0), modbusSerial);
|
||||||
|
}
|
||||||
|
|
||||||
|
int out_Modbus::sendModbus(char * paramName, uint32_t value, uint8_t regType)
|
||||||
|
{
|
||||||
|
if (!store) return -1;
|
||||||
|
aJsonObject * templateParamObj = aJson.getObjectItem(store->parameters, paramName);
|
||||||
|
if (!templateParamObj) return -1;
|
||||||
|
aJsonObject * regObj = aJson.getObjectItem(templateParamObj, "reg");
|
||||||
|
if (!regObj) return -2;
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
|
// int8_t regType = PAR_I16;
|
||||||
|
// aJsonObject * typeObj = aJson.getObjectItem(templateParamObj, "type");
|
||||||
|
// if (typeObj && typeObj->type == aJson_String) regType=str2regSize(typeObj->valuestring);
|
||||||
|
|
||||||
|
switch(regType) {
|
||||||
|
case PAR_I16:
|
||||||
|
case PAR_U16:
|
||||||
|
case PAR_TENS:
|
||||||
|
res = node.writeSingleRegister(regObj->valueint,value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PAR_I32:
|
||||||
|
case PAR_U32:
|
||||||
|
res = node.writeSingleRegister(regObj->valueint,value & 0xFFFF);
|
||||||
|
res += node.writeSingleRegister(regObj->valueint+1,value >> 16) ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAR_U8L:
|
||||||
|
res = node.writeSingleRegister(regObj->valueint,value & 0xFF);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAR_U8H:
|
||||||
|
res = node.writeSingleRegister(regObj->valueint,(value & 0xFFFF)>> 8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debugSerial<<F("MB_SEND Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
|
||||||
|
return ( res == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int out_Modbus::Poll(short cause)
|
||||||
|
{
|
||||||
|
bool lineInitialized = false;
|
||||||
|
|
||||||
|
if (modbusBusy || (Status() != CST_INITIALIZED)) return 0;
|
||||||
|
|
||||||
|
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||||
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
|
{
|
||||||
|
aJsonObject *execObj = itemParametersObj->child;
|
||||||
|
while (execObj && execObj->type == aJson_Object)
|
||||||
|
{
|
||||||
|
if ((execObj->subtype & MB_NEED_SEND) && !(execObj->subtype & MB_SEND_ERROR))
|
||||||
|
{
|
||||||
|
aJsonObject *outValue = aJson.getObjectItem(execObj,"@V");
|
||||||
|
if (outValue)
|
||||||
|
{
|
||||||
|
modbusBusy=1;
|
||||||
|
if (!lineInitialized)
|
||||||
|
{
|
||||||
|
lineInitialized=true;
|
||||||
|
initLine();
|
||||||
|
}
|
||||||
|
switch (sendModbus(execObj->name,outValue->valueint,outValue->subtype))
|
||||||
|
{
|
||||||
|
case 1: //success
|
||||||
|
execObj->subtype&=~ MB_NEED_SEND;
|
||||||
|
break;
|
||||||
|
case 0: //fault
|
||||||
|
execObj->subtype |= MB_SEND_ERROR;
|
||||||
|
break;
|
||||||
|
default: //param not found
|
||||||
|
errorSerial<<F("MBus param ")<<execObj->name<<F(" not found")<<endl;
|
||||||
|
execObj->subtype&=~ MB_NEED_SEND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
execObj=execObj->next;
|
||||||
|
}
|
||||||
|
modbusBusy=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isTimeOver(store->timestamp,millis(),store->pollingInterval))
|
||||||
|
{
|
||||||
|
|
||||||
|
// Clean_up SEND_ERROR flag
|
||||||
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
|
{
|
||||||
|
aJsonObject *execObj = itemParametersObj->child;
|
||||||
|
while (execObj && execObj->type == aJson_Object)
|
||||||
|
{
|
||||||
|
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
||||||
|
execObj=execObj->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if some polling configured
|
||||||
|
if (store->pollingRegisters || store->pollingIrs)
|
||||||
|
{
|
||||||
|
debugSerial<<F("Poll ")<< item->itemArr->name << endl;
|
||||||
|
modbusBusy=1;
|
||||||
|
|
||||||
|
if (!lineInitialized)
|
||||||
|
{
|
||||||
|
lineInitialized=true;
|
||||||
|
initLine();
|
||||||
|
}
|
||||||
|
|
||||||
pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE);
|
pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE);
|
||||||
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
|
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
|
||||||
|
|
||||||
store->timestamp=millisNZ();
|
|
||||||
debugSerial<<F("endPoll ")<< item->itemArr->name << endl;
|
debugSerial<<F("endPoll ")<< item->itemArr->name << endl;
|
||||||
|
|
||||||
//Non blocking waiting to release line
|
//Non blocking waiting to release line
|
||||||
@@ -405,13 +508,15 @@ if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() =
|
|||||||
|
|
||||||
modbusBusy =0;
|
modbusBusy =0;
|
||||||
}
|
}
|
||||||
|
store->timestamp=millisNZ();
|
||||||
|
}
|
||||||
|
|
||||||
return store->pollingInterval;
|
return store->pollingInterval;
|
||||||
};
|
};
|
||||||
|
|
||||||
int out_Modbus::getChanType()
|
int out_Modbus::getChanType()
|
||||||
{
|
{
|
||||||
return CH_MODBUS;
|
return CH_MBUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -423,41 +528,87 @@ int out_Modbus::getChanType()
|
|||||||
|
|
||||||
int out_Modbus::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_Modbus::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
||||||
{
|
{
|
||||||
return 0;
|
|
||||||
//int chActive = item->isActive();
|
|
||||||
//bool toExecute = (chActive>0);
|
|
||||||
//itemCmd st(ST_UINT32,CMD_VOID);
|
|
||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
aJsonObject *templateParamObj = NULL;
|
aJsonObject *templateParamObj = NULL;
|
||||||
short mappedCmdVal = 0;
|
short mappedCmdVal = 0;
|
||||||
|
|
||||||
|
char * suffixStr = subItem;
|
||||||
|
|
||||||
// trying to find parameter in template with name == subItem (NB!! standard suffixes dint working here)
|
// trying to find parameter in template with name == subItem (NB!! standard suffixes dint working here)
|
||||||
if (subItem && strlen (subItem) && store) templateParamObj = aJson.getObjectItem(store->parameters, subItem);
|
if (subItem && strlen (subItem) && store) templateParamObj = aJson.getObjectItem(store->parameters, subItem);
|
||||||
|
|
||||||
if (!templateParamObj && store)
|
if (!templateParamObj && store)
|
||||||
{
|
{
|
||||||
// Trying to find template parameter where id == suffixCode
|
// Fallback - Trying to find template parameter where id == suffixCode
|
||||||
templateParamObj = store->parameters->child;
|
templateParamObj = store->parameters->child;
|
||||||
|
|
||||||
while (templateParamObj)
|
while (templateParamObj)
|
||||||
{
|
{
|
||||||
//aJsonObject *regObj = aJson.getObjectItem(paramObj, "reg");
|
//aJsonObject *regObj = aJson.getObjectItem(paramObj, "reg");
|
||||||
aJsonObject *idObj = aJson.getObjectItem(templateParamObj, "id");
|
aJsonObject *idObj = aJson.getObjectItem(templateParamObj, "id");
|
||||||
if (idObj->type==aJson_Int && idObj->valueint == suffixCode) break;
|
if (idObj->type==aJson_Int && idObj->valueint == suffixCode)
|
||||||
|
{
|
||||||
|
suffixStr=templateParamObj->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
aJsonObject *mapObj = aJson.getObjectItem(templateParamObj, "mapcmd");
|
// aJsonObject *mapObj = aJson.getObjectItem(templateParamObj, "mapcmd");
|
||||||
if (mapObj && (mappedCmdVal = cmd.doReverseMappingCmd(mapObj))) break;
|
// if (mapObj && (mappedCmdVal = cmd.doReverseMappingCmd(mapObj))) break;
|
||||||
|
|
||||||
templateParamObj=templateParamObj->next;
|
templateParamObj=templateParamObj->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
|
if (templateParamObj)
|
||||||
// aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
{
|
||||||
// aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
// We have find template for suffix or suffixCode
|
||||||
// uint16_t data = node.getResponseBuffer(posInBuffer);
|
long Value = 0;
|
||||||
|
int8_t regType = PAR_I16;
|
||||||
|
aJsonObject * typeObj = aJson.getObjectItem(templateParamObj, "type");
|
||||||
|
|
||||||
|
if (typeObj && typeObj->type == aJson_String) regType=str2regSize(typeObj->valuestring);
|
||||||
|
switch(regType) {
|
||||||
|
case PAR_I16:
|
||||||
|
case PAR_I32:
|
||||||
|
case PAR_U32:
|
||||||
|
case PAR_U8L:
|
||||||
|
case PAR_U8H:
|
||||||
|
Value=cmd.getInt();
|
||||||
|
break;
|
||||||
|
case PAR_TENS:
|
||||||
|
Value=cmd.getTens();
|
||||||
|
}
|
||||||
|
|
||||||
|
debugSerial<<F("MB suffix:")<<suffixStr<< F(" Val: ")<<Value<<endl;
|
||||||
|
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||||
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
|
{
|
||||||
|
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
||||||
|
if (execObj && execObj->type == aJson_Object)
|
||||||
|
{
|
||||||
|
execObj->subtype |= MB_NEED_SEND;
|
||||||
|
|
||||||
|
aJsonObject *outValue = aJson.getObjectItem(execObj,"@V");
|
||||||
|
if (outValue)
|
||||||
|
{
|
||||||
|
outValue->valueint=Value;
|
||||||
|
outValue->subtype =regType;
|
||||||
|
}
|
||||||
|
else //No container to store value yet
|
||||||
|
{
|
||||||
|
debugSerial<<F("Add @V: ")<<execObj->name<<endl;
|
||||||
|
aJson.addNumberToObject(execObj, "@V", Value);
|
||||||
|
outValue = aJson.getObjectItem(execObj,"@V");
|
||||||
|
if (outValue) outValue->subtype =regType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else errorSerial<<F("No template for ")<<subItem<<F("/")<<suffixCode<<endl;
|
||||||
|
|
||||||
|
|
||||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public:
|
|||||||
aJsonObject * parameters;
|
aJsonObject * parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MB_NEED_SEND 1
|
||||||
|
#define MB_SEND_ERROR 2
|
||||||
|
|
||||||
|
|
||||||
class out_Modbus : public abstractOut {
|
class out_Modbus : public abstractOut {
|
||||||
@@ -42,5 +44,7 @@ protected:
|
|||||||
bool getConfig();
|
bool getConfig();
|
||||||
int findRegister(int registerNum, int posInBuffer, int regType);
|
int findRegister(int registerNum, int posInBuffer, int regType);
|
||||||
void pollModbus(aJsonObject * reg, int regType);
|
void pollModbus(aJsonObject * reg, int regType);
|
||||||
|
void initLine();
|
||||||
|
int sendModbus(char * paramName, uint32_t value, uint8_t regType);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user