modbus/modbus.py
changeset 2722 5d72a52b8f9c
parent 2721 367eb26972b1
child 2723 cde2e410b874
equal deleted inserted replaced
2721:367eb26972b1 2722:5d72a52b8f9c
   450         # These flags are mapped onto located variables and therefore available to the user programs
   450         # These flags are mapped onto located variables and therefore available to the user programs
   451         # May be used to detect communication errors.
   451         # May be used to detect communication errors.
   452         # execute the Modbus request.
   452         # execute the Modbus request.
   453         # NOTE: If the Modbus slave has a 'current_location' of
   453         # NOTE: If the Modbus slave has a 'current_location' of
   454         #          %QX1.2
   454         #          %QX1.2
   455         #       then the "Modbus Read Request Counter" will be
   455         #       then the "Modbus Read Request Counter"  will be %MD1.2.0
   456         #          %MD1.2.0
   456         #       then the "Modbus Write Request Counter" will be %MD1.2.1
   457         #       then the "Modbus Write Request Counter" will be
   457         #       then the "Modbus Read Request Flag"     will be %MD1.2.2
   458         #          %MD1.2.1
   458         #       then the "Modbus Write Request Flag"    will be %MD1.2.3
   459         #
   459         #
   460         # Note that any MemoryArea contained under this server/slave
   460         # Note that any MemoryArea contained under this server/slave
   461         # will ocupy the locations of type
   461         # will ocupy the locations of type
   462         #          %MX or %MW
   462         #          %MX or %MW
   463         # which will never clash with the %MD used here.
   463         # which will never clash with the %MD used here.
   465         # will ocupy locations with
   465         # will ocupy locations with
   466         #           %M1.2.a.b (with a and b being numbers in range 0, 1, ...)
   466         #           %M1.2.a.b (with a and b being numbers in range 0, 1, ...)
   467         # and therefore never ocupy the locations
   467         # and therefore never ocupy the locations
   468         #           %M1.2.0
   468         #           %M1.2.0
   469         #           %M1.2.1
   469         #           %M1.2.1
       
   470         #           %M1.2.2
       
   471         #           %M1.2.3
   470         # used by the following flags/counters.
   472         # used by the following flags/counters.
   471         entries = []
   473         entries = []
   472         entries.append({
   474         entries.append({
   473             "name": "Modbus Read Request Counter",
   475             "name": "Modbus Read Request Counter",
   474             "type": LOCATION_VAR_MEMORY,
   476             "type": LOCATION_VAR_MEMORY,
   484             "size": 32,           # UDINT flag
   486             "size": 32,           # UDINT flag
   485             "IEC_type": "UDINT",  # UDINT flag
   487             "IEC_type": "UDINT",  # UDINT flag
   486             "var_name": "var_name",
   488             "var_name": "var_name",
   487             "location": "D" + ".".join([str(i) for i in current_location]) + ".1",
   489             "location": "D" + ".".join([str(i) for i in current_location]) + ".1",
   488             "description": "Modbus write request counter",
   490             "description": "Modbus write request counter",
       
   491             "children": []})        
       
   492         entries.append({
       
   493             "name": "Modbus Read Request Flag",
       
   494             "type": LOCATION_VAR_MEMORY,
       
   495             "size": 1,            # BOOL flag
       
   496             "IEC_type": "BOOL",   # BOOL flag
       
   497             "var_name": "var_name",
       
   498             "location": "X" + ".".join([str(i) for i in current_location]) + ".2",
       
   499             "description": "Modbus read request flag",
       
   500             "children": []})        
       
   501         entries.append({
       
   502             "name": "Modbus write Request Flag",
       
   503             "type": LOCATION_VAR_MEMORY,
       
   504             "size": 1,            # BOOL flag
       
   505             "IEC_type": "BOOL",   # BOOL flag
       
   506             "var_name": "var_name",
       
   507             "location": "X" + ".".join([str(i) for i in current_location]) + ".3",
       
   508             "description": "Modbus write request flag",
   489             "children": []})        
   509             "children": []})        
   490         # recursively call all the Memory Areas under this Modbus server/save
   510         # recursively call all the Memory Areas under this Modbus server/save
   491         # i.e., all the children objects which will be of class _MemoryAreaPlug
   511         # i.e., all the children objects which will be of class _MemoryAreaPlug
   492         for child in self.IECSortedChildren():
   512         for child in self.IECSortedChildren():
   493             entries.append(child.GetVariableLocationTree())
   513             entries.append(child.GetVariableLocationTree())
   687         # These flags are mapped onto located variables and therefore available to the user programs
   707         # These flags are mapped onto located variables and therefore available to the user programs
   688         # May be used to detect communication errors.
   708         # May be used to detect communication errors.
   689         # execute the Modbus request.
   709         # execute the Modbus request.
   690         # NOTE: If the Modbus slave has a 'current_location' of
   710         # NOTE: If the Modbus slave has a 'current_location' of
   691         #          %QX1.2
   711         #          %QX1.2
   692         #       then the "Modbus Read Request Counter" will be
   712         #       then the "Modbus Read Request Counter"  will be %MD1.2.0
   693         #          %MD1.2.0
   713         #       then the "Modbus Write Request Counter" will be %MD1.2.1
   694         #       then the "Modbus Write Request Counter" will be
   714         #       then the "Modbus Read Request Flag"     will be %MD1.2.2
   695         #          %MD1.2.1
   715         #       then the "Modbus Write Request Flag"    will be %MD1.2.3
   696         #
   716         #
   697         # Note that any MemoryArea contained under this server/slave
   717         # Note that any MemoryArea contained under this server/slave
   698         # will ocupy the locations of type
   718         # will ocupy the locations of type
   699         #          %MX or %MW
   719         #          %MX or %MW
   700         # which will never clash with the %MD used here.
   720         # which will never clash with the %MD used here.
   702         # will ocupy locations with
   722         # will ocupy locations with
   703         #           %M1.2.a.b (with a and b being numbers in range 0, 1, ...)
   723         #           %M1.2.a.b (with a and b being numbers in range 0, 1, ...)
   704         # and therefore never ocupy the locations
   724         # and therefore never ocupy the locations
   705         #           %M1.2.0
   725         #           %M1.2.0
   706         #           %M1.2.1
   726         #           %M1.2.1
       
   727         #           %M1.2.2
       
   728         #           %M1.2.3
   707         # used by the following flags/counters.
   729         # used by the following flags/counters.
   708         entries = []
   730         entries = []
   709         entries.append({
   731         entries.append({
   710             "name": "Modbus Read Request Counter",
   732             "name": "Modbus Read Request Counter",
   711             "type": LOCATION_VAR_MEMORY,
   733             "type": LOCATION_VAR_MEMORY,
   721             "size": 32,           # UDINT flag
   743             "size": 32,           # UDINT flag
   722             "IEC_type": "UDINT",  # UDINT flag
   744             "IEC_type": "UDINT",  # UDINT flag
   723             "var_name": "var_name",
   745             "var_name": "var_name",
   724             "location": "D" + ".".join([str(i) for i in current_location]) + ".1",
   746             "location": "D" + ".".join([str(i) for i in current_location]) + ".1",
   725             "description": "Modbus write request counter",
   747             "description": "Modbus write request counter",
       
   748             "children": []})        
       
   749         entries.append({
       
   750             "name": "Modbus Read Request Flag",
       
   751             "type": LOCATION_VAR_MEMORY,
       
   752             "size": 1,            # BOOL flag
       
   753             "IEC_type": "BOOL",   # BOOL flag
       
   754             "var_name": "var_name",
       
   755             "location": "X" + ".".join([str(i) for i in current_location]) + ".2",
       
   756             "description": "Modbus read request flag",
       
   757             "children": []})        
       
   758         entries.append({
       
   759             "name": "Modbus write Request Flag",
       
   760             "type": LOCATION_VAR_MEMORY,
       
   761             "size": 1,            # BOOL flag
       
   762             "IEC_type": "BOOL",   # BOOL flag
       
   763             "var_name": "var_name",
       
   764             "location": "X" + ".".join([str(i) for i in current_location]) + ".3",
       
   765             "description": "Modbus write request flag",
   726             "children": []})        
   766             "children": []})        
   727         # recursively call all the Memory Areas under this Modbus server/save
   767         # recursively call all the Memory Areas under this Modbus server/save
   728         # i.e., all the children objects which will be of class _MemoryAreaPlug
   768         # i.e., all the children objects which will be of class _MemoryAreaPlug
   729         for child in self.IECSortedChildren():
   769         for child in self.IECSortedChildren():
   730             entries.append(child.GetVariableLocationTree())
   770             entries.append(child.GetVariableLocationTree())
   922                 tcpserver_node_count += 1
   962                 tcpserver_node_count += 1
   923                 new_node = GetTCPServerNodePrinted(self, child)
   963                 new_node = GetTCPServerNodePrinted(self, child)
   924                 if new_node is None:
   964                 if new_node is None:
   925                     return [], "", False
   965                     return [], "", False
   926                 server_node_list.append(new_node)                
   966                 server_node_list.append(new_node)                
   927                 #        We currently add 2 flags/counters to each Modbus server/slave
   967                 #        We currently add 4 flags/counters to each Modbus server/slave
   928                 #
   968                 #
   929                 # TODO: fix comment
   969                 #        We add the Modbus read/write counter/flag to each Modbus slave/server
   930                 #        We add the "Execution Control Flag" to each client request (one flag per request)
   970                 #        to allow the user program to determine if the slave is being actively
   931                 #        to allow the user program to control when to execute the request (if not executed periodically)
   971                 #        read from or written by by a remote Modbus client.
   932                 #        While all Modbus registers/coils are mapped onto a location
       
   933                 #        with 4 numbers (e.g. %QX0.1.2.55), this control flag is mapped
       
   934                 #        onto a location with 4 numbers (e.g. %QX0.1.2.0.0), where the last
       
   935                 #        two numbers are always '0.0', and the first two identify the request.
       
   936                 #        In the following if, we check for this condition by checking
       
   937                 #        if there are at least 4 or more number in the location's address.
       
   938                 for iecvar in child.GetLocations():
   972                 for iecvar in child.GetLocations():
   939                     #print "child" + repr(iecvar)
   973                     #print "child" + repr(iecvar)
   940                     if (len(iecvar["LOC"]) == 3) and (str(iecvar["NAME"]) not in loc_vars_list):
   974                     if (len(iecvar["LOC"]) == 3) and (str(iecvar["NAME"]) not in loc_vars_list):
   941                         # Add if it is a "Modbus Read Request Counter" (mapped onto %MDa.b.0), so last number is a '0'
   975                         # Add if it is a "Modbus Read Request Counter" (mapped onto %MDa.b.0), so last number is a '0'
   942                         if iecvar["LOC"][2] == 0:
   976                         if iecvar["LOC"][2] == 0:
   943                             loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_counter;" % (server_id))
   977                             loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_counter;" % (server_id))
   944                             loc_vars_list.append(str(iecvar["NAME"]))
   978                             loc_vars_list.append(str(iecvar["NAME"]))
   945                         # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.1), so last number is a '1'
   979                         # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.1), so last number is a '1'
   946                         if iecvar["LOC"][2] == 1:
   980                         if iecvar["LOC"][2] == 1:
   947                             loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_counter;" % (server_id))
   981                             loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_counter;" % (server_id))
       
   982                             loc_vars_list.append(str(iecvar["NAME"]))
       
   983                         # Add if it is a "Modbus Read Request Flag" (mapped onto %MDa.b.2), so last number is a '2'
       
   984                         if iecvar["LOC"][2] == 2:
       
   985                             loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_flag;" % (server_id))
       
   986                             loc_vars_list.append(str(iecvar["NAME"]))
       
   987                         # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.3), so last number is a '3'
       
   988                         if iecvar["LOC"][2] == 3:
       
   989                             loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_flag;" % (server_id))
   948                             loc_vars_list.append(str(iecvar["NAME"]))
   990                             loc_vars_list.append(str(iecvar["NAME"]))
   949                 
   991                 
   950                 for subchild in child.IECSortedChildren():
   992                 for subchild in child.IECSortedChildren():
   951                     new_memarea = GetTCPServerMemAreaPrinted(self, subchild, nodeid)
   993                     new_memarea = GetTCPServerMemAreaPrinted(self, subchild, nodeid)
   952                     if new_memarea is None:
   994                     if new_memarea is None:
   973                 rtuserver_node_count += 1
  1015                 rtuserver_node_count += 1
   974                 new_node = GetRTUSlaveNodePrinted(self, child)
  1016                 new_node = GetRTUSlaveNodePrinted(self, child)
   975                 if new_node is None:
  1017                 if new_node is None:
   976                     return [], "", False
  1018                     return [], "", False
   977                 server_node_list.append(new_node)
  1019                 server_node_list.append(new_node)
       
  1020                 #        We currently add 4 flags/counters to each Modbus server/slave
   978                 #
  1021                 #
       
  1022                 #        We add the Modbus read/write counter/flag to each Modbus slave/server
       
  1023                 #        to allow the user program to determine if the slave is being actively
       
  1024                 #        read from or written by by a remote Modbus client.
       
  1025                 for iecvar in child.GetLocations():
       
  1026                     #print "child" + repr(iecvar)
       
  1027                     if (len(iecvar["LOC"]) == 3) and (str(iecvar["NAME"]) not in loc_vars_list):
       
  1028                         # Add if it is a "Modbus Read Request Counter" (mapped onto %MDa.b.0), so last number is a '0'
       
  1029                         if iecvar["LOC"][2] == 0:
       
  1030                             loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_counter;" % (server_id))
       
  1031                             loc_vars_list.append(str(iecvar["NAME"]))
       
  1032                         # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.1), so last number is a '1'
       
  1033                         if iecvar["LOC"][2] == 1:
       
  1034                             loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_counter;" % (server_id))
       
  1035                             loc_vars_list.append(str(iecvar["NAME"]))
       
  1036                         # Add if it is a "Modbus Read Request Flag" (mapped onto %MDa.b.2), so last number is a '2'
       
  1037                         if iecvar["LOC"][2] == 2:
       
  1038                             loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_flag;" % (server_id))
       
  1039                             loc_vars_list.append(str(iecvar["NAME"]))
       
  1040                         # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.3), so last number is a '3'
       
  1041                         if iecvar["LOC"][2] == 3:
       
  1042                             loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_flag;" % (server_id))
       
  1043                             loc_vars_list.append(str(iecvar["NAME"]))
       
  1044 
   979                 for subchild in child.IECSortedChildren():
  1045                 for subchild in child.IECSortedChildren():
   980                     new_memarea = GetTCPServerMemAreaPrinted(
  1046                     new_memarea = GetTCPServerMemAreaPrinted(
   981                         self, subchild, nodeid)
  1047                         self, subchild, nodeid)
   982                     if new_memarea is None:
  1048                     if new_memarea is None:
   983                         return [], "", False
  1049                         return [], "", False