diff --git a/lighthub/itemCmd.cpp b/lighthub/itemCmd.cpp index 1b51403..69205ff 100644 --- a/lighthub/itemCmd.cpp +++ b/lighthub/itemCmd.cpp @@ -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() { diff --git a/lighthub/itemCmd.h b/lighthub/itemCmd.h index 573604a..9eb6d67 100644 --- a/lighthub/itemCmd.h +++ b/lighthub/itemCmd.h @@ -197,6 +197,7 @@ public: bool incrementS(int16_t); long int getInt(); + long int getTens(); float getFloat(); char * getString(); long int getSingleInt(); diff --git a/lighthub/modules/out_modbus.cpp b/lighthub/modules/out_modbus.cpp index 5a3ab02..0034bfa 100644 --- a/lighthub/modules/out_modbus.cpp +++ b/lighthub/modules/out_modbus.cpp @@ -171,8 +171,6 @@ if (!store) store->timestamp=millisNZ(); if (getConfig()) { - //item->clearFlag(ACTION_NEEDED); - //item->clearFlag(ACTION_IN_PROCESS); infoSerial<itemArr->name<driverStatus = CST_INITIALIZED; return 1; @@ -285,7 +283,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType) case PAR_U8H: //is8bit=true; - param = data << 8; + param = (data & 0xFF00) >> 8; mappedParam.Int((uint32_t)param); break; @@ -371,13 +369,9 @@ 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<itemArr->name << endl; - modbusBusy=1; - //store->serialParam=(USARTClass::USARTModes) SERIAL_8N1; +//store->serialParam=(USARTClass::USARTModes) SERIAL_8N1; #if defined (__SAM3X8E__) modbusSerial.begin(store->baud, static_cast (store->serialParam)); #elif defined (ARDUINO_ARCH_ESP8266) @@ -391,12 +385,121 @@ if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() = #endif debugSerial<< store->baud << F("---")<< store->serialParam<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<valueint<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<name<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<itemArr->name << endl; + modbusBusy=1; + + if (!lineInitialized) + { + lineInitialized=true; + initLine(); + } pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE); pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE); - - store->timestamp=millisNZ(); - debugSerial<itemArr->name << endl; + debugSerial<itemArr->name << endl; //Non blocking waiting to release line uint32_t time = millis(); @@ -405,13 +508,15 @@ if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() = modbusBusy =0; } + store->timestamp=millisNZ(); +} return store->pollingInterval; }; 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) { - return 0; -//int chActive = item->isActive(); -//bool toExecute = (chActive>0); -//itemCmd st(ST_UINT32,CMD_VOID); int suffixCode = cmd.getSuffix(); aJsonObject *templateParamObj = NULL; short mappedCmdVal = 0; +char * suffixStr = subItem; + // 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 (!templateParamObj && store) { - // Trying to find template parameter where id == suffixCode + // Fallback - Trying to find template parameter where id == suffixCode templateParamObj = store->parameters->child; while (templateParamObj) { //aJsonObject *regObj = aJson.getObjectItem(paramObj, "reg"); 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"); - if (mapObj && (mappedCmdVal = cmd.doReverseMappingCmd(mapObj))) break; + // aJsonObject *mapObj = aJson.getObjectItem(templateParamObj, "mapcmd"); + // if (mapObj && (mappedCmdVal = cmd.doReverseMappingCmd(mapObj))) break; templateParamObj=templateParamObj->next; } } -// aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type"); -// aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map"); -// aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2); -// uint16_t data = node.getResponseBuffer(posInBuffer); +if (templateParamObj) +{ +// We have find template for suffix or suffixCode +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<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<name<subtype =regType; + } + } + } + + + +} +else errorSerial<