diff -r 1b4b335e19ea -r 990004083eb8 modbus/modbus.py --- a/modbus/modbus.py Wed Nov 13 11:21:04 2019 +0100 +++ b/modbus/modbus.py Thu May 28 10:54:48 2020 +0100 @@ -83,6 +83,7 @@ + @@ -115,7 +116,29 @@ datatacc = modbus_function_dict[function][6] # 'Coil', 'Holding Register', 'Input Discrete' or 'Input Register' dataname = modbus_function_dict[function][7] + # start off with a boolean entry + # This is a flag used to allow the user program to control when to + # execute the Modbus request. + # NOTE: If the Modbus request has a 'current_location' of + # %QX1.2.3 + # then the execution control flag will be + # %QX1.2.3.0.0 + # and all the Modbus registers/coils will be + # %QX1.2.3.0 + # %QX1.2.3.1 + # %QX1.2.3.2 + # .. + # %QX1.2.3.n entries = [] + entries.append({ + "name": "Exec. request flag", + "type": LOCATION_VAR_MEMORY, + "size": 1, # BOOL flag + "IEC_type": "BOOL", # BOOL flag + "var_name": "var_name", + "location": "X" + ".".join([str(i) for i in current_location]) + ".0.0", + "description": "MB request execution control flag", + "children": []}) for offset in range(address, address + count): entries.append({ "name": dataname + " " + str(offset), @@ -270,7 +293,7 @@ - + @@ -388,7 +411,7 @@ - + @@ -720,12 +743,32 @@ for iecvar in subchild.GetLocations(): # absloute address - start address relative_addr = iecvar["LOC"][3] - int(GetCTVal(subchild, 3)) - # test if relative address in request specified range - if relative_addr in xrange(int(GetCTVal(subchild, 2))): + # test if the located variable + # (a) has relative address in request specified range + # AND is NOT + # (b) is a control flag added by this modbus plugin + # to control its execution at runtime. + # Currently, we only add the "Execution Control Flag" + # to each client request (one flag per request) + # to control when to execute the request (if not executed periodically) + # While all Modbus registers/coils are mapped onto a location + # with 4 numbers (e.g. %QX0.1.2.55), this control flag is mapped + # onto a location with 4 numbers (e.g. %QX0.1.2.0.0), where the last + # two numbers are always '0.0', and the first two identify the request. + # In the following if, we check for this condition by checking + # if their are at least 4 or more number in the location's address. + if ( relative_addr in xrange(int(GetCTVal(subchild, 2))) # condition (a) explained above + and len(iecvar["LOC"]) < 5): # condition (b) explained above if str(iecvar["NAME"]) not in loc_vars_list: loc_vars.append( "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr)) loc_vars_list.append(str(iecvar["NAME"])) + # Now add the located variable in case it is a flag (condition (b) above + if len(iecvar["LOC"]) >= 5: # condition (b) explained above + if str(iecvar["NAME"]) not in loc_vars_list: + loc_vars.append( + "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].flag_exec_req;" % (client_requestid)) + loc_vars_list.append(str(iecvar["NAME"])) client_requestid += 1 tcpclient_node_count += 1 client_nodeid += 1 @@ -745,12 +788,32 @@ for iecvar in subchild.GetLocations(): # absloute address - start address relative_addr = iecvar["LOC"][3] - int(GetCTVal(subchild, 3)) - # test if relative address in request specified range - if relative_addr in xrange(int(GetCTVal(subchild, 2))): + # test if the located variable + # (a) has relative address in request specified range + # AND is NOT + # (b) is a control flag added by this modbus plugin + # to control its execution at runtime. + # Currently, we only add the "Execution Control Flag" + # to each client request (one flag per request) + # to control when to execute the request (if not executed periodically) + # While all Modbus registers/coils are mapped onto a location + # with 4 numbers (e.g. %QX0.1.2.55), this control flag is mapped + # onto a location with 4 numbers (e.g. %QX0.1.2.0.0), where the last + # two numbers are always '0.0', and the first two identify the request. + # In the following if, we check for this condition by checking + # if their are at least 4 or more number in the location's address. + if ( relative_addr in xrange(int(GetCTVal(subchild, 2))) # condition (a) explained above + and len(iecvar["LOC"]) < 5): # condition (b) explained above if str(iecvar["NAME"]) not in loc_vars_list: loc_vars.append( "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr)) loc_vars_list.append(str(iecvar["NAME"])) + # Now add the located variable in case it is a flag (condition (b) above + if len(iecvar["LOC"]) >= 5: # condition (b) explained above + if str(iecvar["NAME"]) not in loc_vars_list: + loc_vars.append( + "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].flag_exec_req;" % (client_requestid)) + loc_vars_list.append(str(iecvar["NAME"])) client_requestid += 1 rtuclient_node_count += 1 client_nodeid += 1