modbus/modbus.py
changeset 2647 990004083eb8
parent 2589 d94d4f396bbf
child 2648 e4ab768170f9
equal deleted inserted replaced
2640:1b4b335e19ea 2647:990004083eb8
    81                     <xsd:minInclusive value="1"/>
    81                     <xsd:minInclusive value="1"/>
    82                     <xsd:maxInclusive value="100000"/>
    82                     <xsd:maxInclusive value="100000"/>
    83                 </xsd:restriction>
    83                 </xsd:restriction>
    84             </xsd:simpleType>
    84             </xsd:simpleType>
    85           </xsd:attribute>
    85           </xsd:attribute>
       
    86           <xsd:attribute name="Write_on_change" type="xsd:boolean" use="optional" default="false"/>
    86         </xsd:complexType>
    87         </xsd:complexType>
    87       </xsd:element>
    88       </xsd:element>
    88     </xsd:schema>
    89     </xsd:schema>
    89     """
    90     """
    90 
    91 
   113         # datazone = modbus_function_dict[function][5]
   114         # datazone = modbus_function_dict[function][5]
   114         # 'X' for bits, 'W' for words
   115         # 'X' for bits, 'W' for words
   115         datatacc = modbus_function_dict[function][6]
   116         datatacc = modbus_function_dict[function][6]
   116         # 'Coil', 'Holding Register', 'Input Discrete' or 'Input Register'
   117         # 'Coil', 'Holding Register', 'Input Discrete' or 'Input Register'
   117         dataname = modbus_function_dict[function][7]
   118         dataname = modbus_function_dict[function][7]
       
   119         # start off with a boolean entry
       
   120         # This is a flag used to allow the user program to control when to 
       
   121         # execute the Modbus request.
       
   122         # NOTE: If the Modbus request has a 'current_location' of
       
   123         #          %QX1.2.3
       
   124         #       then the execution control flag will be
       
   125         #          %QX1.2.3.0.0
       
   126         #       and all the Modbus registers/coils will be
       
   127         #          %QX1.2.3.0
       
   128         #          %QX1.2.3.1
       
   129         #          %QX1.2.3.2
       
   130         #            ..
       
   131         #          %QX1.2.3.n
   118         entries = []
   132         entries = []
       
   133         entries.append({
       
   134             "name": "Exec. request flag",
       
   135             "type": LOCATION_VAR_MEMORY,
       
   136             "size": 1,           # BOOL flag
       
   137             "IEC_type": "BOOL",  # BOOL flag
       
   138             "var_name": "var_name",
       
   139             "location": "X" + ".".join([str(i) for i in current_location]) + ".0.0",
       
   140             "description": "MB request execution control flag",
       
   141             "children": []})        
   119         for offset in range(address, address + count):
   142         for offset in range(address, address + count):
   120             entries.append({
   143             entries.append({
   121                 "name": dataname + " " + str(offset),
   144                 "name": dataname + " " + str(offset),
   122                 "type": LOCATION_VAR_MEMORY,
   145                 "type": LOCATION_VAR_MEMORY,
   123                 "size": datasize,
   146                 "size": datasize,
   268           <xsd:attribute name="Remote_IP_Address" type="xsd:string" use="optional" default="localhost"/>
   291           <xsd:attribute name="Remote_IP_Address" type="xsd:string" use="optional" default="localhost"/>
   269           <xsd:attribute name="Remote_Port_Number" type="xsd:string" use="optional" default="502"/>
   292           <xsd:attribute name="Remote_Port_Number" type="xsd:string" use="optional" default="502"/>
   270           <xsd:attribute name="Invocation_Rate_in_ms" use="optional" default="100">
   293           <xsd:attribute name="Invocation_Rate_in_ms" use="optional" default="100">
   271             <xsd:simpleType>
   294             <xsd:simpleType>
   272                 <xsd:restriction base="xsd:unsignedLong">
   295                 <xsd:restriction base="xsd:unsignedLong">
   273                     <xsd:minInclusive value="1"/>
   296                     <xsd:minInclusive value="0"/>
   274                     <xsd:maxInclusive value="2147483647"/>
   297                     <xsd:maxInclusive value="2147483647"/>
   275                 </xsd:restriction>
   298                 </xsd:restriction>
   276             </xsd:simpleType>
   299             </xsd:simpleType>
   277           </xsd:attribute>
   300           </xsd:attribute>
   278         </xsd:complexType>
   301         </xsd:complexType>
   386           <xsd:attribute name="Parity"      type="xsd:string"  use="optional" default="even"/>
   409           <xsd:attribute name="Parity"      type="xsd:string"  use="optional" default="even"/>
   387           <xsd:attribute name="Stop_Bits"   type="xsd:string"  use="optional" default="1"/>
   410           <xsd:attribute name="Stop_Bits"   type="xsd:string"  use="optional" default="1"/>
   388           <xsd:attribute name="Invocation_Rate_in_ms" use="optional" default="100">
   411           <xsd:attribute name="Invocation_Rate_in_ms" use="optional" default="100">
   389             <xsd:simpleType>
   412             <xsd:simpleType>
   390                 <xsd:restriction base="xsd:integer">
   413                 <xsd:restriction base="xsd:integer">
   391                     <xsd:minInclusive value="1"/>
   414                     <xsd:minInclusive value="0"/>
   392                     <xsd:maxInclusive value="2147483647"/>
   415                     <xsd:maxInclusive value="2147483647"/>
   393                 </xsd:restriction>
   416                 </xsd:restriction>
   394             </xsd:simpleType>
   417             </xsd:simpleType>
   395           </xsd:attribute>
   418           </xsd:attribute>
   396         </xsd:complexType>
   419         </xsd:complexType>
   718                         return [], "", False
   741                         return [], "", False
   719                     client_request_list.append(new_req)
   742                     client_request_list.append(new_req)
   720                     for iecvar in subchild.GetLocations():
   743                     for iecvar in subchild.GetLocations():
   721                         # absloute address - start address
   744                         # absloute address - start address
   722                         relative_addr = iecvar["LOC"][3] - int(GetCTVal(subchild, 3))
   745                         relative_addr = iecvar["LOC"][3] - int(GetCTVal(subchild, 3))
   723                         # test if relative address in request specified range
   746                         # test if the located variable 
   724                         if relative_addr in xrange(int(GetCTVal(subchild, 2))):
   747                         #    (a) has relative address in request specified range
       
   748                         #  AND is NOT
       
   749                         #    (b) is a control flag added by this modbus plugin
       
   750                         #        to control its execution at runtime.
       
   751                         #        Currently, we only add the "Execution Control Flag"
       
   752                         #        to each client request (one flag per request)
       
   753                         #        to control when to execute the request (if not executed periodically)
       
   754                         #        While all Modbus registers/coils are mapped onto a location
       
   755                         #        with 4 numbers (e.g. %QX0.1.2.55), this control flag is mapped
       
   756                         #        onto a location with 4 numbers (e.g. %QX0.1.2.0.0), where the last
       
   757                         #        two numbers are always '0.0', and the first two identify the request.
       
   758                         #        In the following if, we check for this condition by checking
       
   759                         #        if their are at least 4 or more number in the location's address.
       
   760                         if (        relative_addr in xrange(int(GetCTVal(subchild, 2)))  # condition (a) explained above
       
   761                             and len(iecvar["LOC"]) < 5):                                  # condition (b) explained above
   725                             if str(iecvar["NAME"]) not in loc_vars_list:
   762                             if str(iecvar["NAME"]) not in loc_vars_list:
   726                                 loc_vars.append(
   763                                 loc_vars.append(
   727                                     "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr))
   764                                     "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr))
       
   765                                 loc_vars_list.append(str(iecvar["NAME"]))
       
   766                         # Now add the located variable in case it is a flag (condition (b) above
       
   767                         if  len(iecvar["LOC"]) >= 5:       # condition (b) explained above
       
   768                             if str(iecvar["NAME"]) not in loc_vars_list:
       
   769                                 loc_vars.append(
       
   770                                     "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].flag_exec_req;" % (client_requestid))
   728                                 loc_vars_list.append(str(iecvar["NAME"]))
   771                                 loc_vars_list.append(str(iecvar["NAME"]))
   729                     client_requestid += 1
   772                     client_requestid += 1
   730                 tcpclient_node_count += 1
   773                 tcpclient_node_count += 1
   731                 client_nodeid += 1
   774                 client_nodeid += 1
   732             #
   775             #
   743                         return [], "", False
   786                         return [], "", False
   744                     client_request_list.append(new_req)
   787                     client_request_list.append(new_req)
   745                     for iecvar in subchild.GetLocations():
   788                     for iecvar in subchild.GetLocations():
   746                         # absloute address - start address
   789                         # absloute address - start address
   747                         relative_addr = iecvar["LOC"][3] - int(GetCTVal(subchild, 3))
   790                         relative_addr = iecvar["LOC"][3] - int(GetCTVal(subchild, 3))
   748                         # test if relative address in request specified range
   791                         # test if the located variable 
   749                         if relative_addr in xrange(int(GetCTVal(subchild, 2))):
   792                         #    (a) has relative address in request specified range
       
   793                         #  AND is NOT
       
   794                         #    (b) is a control flag added by this modbus plugin
       
   795                         #        to control its execution at runtime.
       
   796                         #        Currently, we only add the "Execution Control Flag"
       
   797                         #        to each client request (one flag per request)
       
   798                         #        to control when to execute the request (if not executed periodically)
       
   799                         #        While all Modbus registers/coils are mapped onto a location
       
   800                         #        with 4 numbers (e.g. %QX0.1.2.55), this control flag is mapped
       
   801                         #        onto a location with 4 numbers (e.g. %QX0.1.2.0.0), where the last
       
   802                         #        two numbers are always '0.0', and the first two identify the request.
       
   803                         #        In the following if, we check for this condition by checking
       
   804                         #        if their are at least 4 or more number in the location's address.
       
   805                         if (        relative_addr in xrange(int(GetCTVal(subchild, 2)))  # condition (a) explained above
       
   806                             and len(iecvar["LOC"]) < 5):                                  # condition (b) explained above
   750                             if str(iecvar["NAME"]) not in loc_vars_list:
   807                             if str(iecvar["NAME"]) not in loc_vars_list:
   751                                 loc_vars.append(
   808                                 loc_vars.append(
   752                                     "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr))
   809                                     "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].plcv_buffer[%d];" % (client_requestid, relative_addr))
       
   810                                 loc_vars_list.append(str(iecvar["NAME"]))
       
   811                         # Now add the located variable in case it is a flag (condition (b) above
       
   812                         if  len(iecvar["LOC"]) >= 5:       # condition (b) explained above
       
   813                             if str(iecvar["NAME"]) not in loc_vars_list:
       
   814                                 loc_vars.append(
       
   815                                     "u16 *" + str(iecvar["NAME"]) + " = &client_requests[%d].flag_exec_req;" % (client_requestid))
   753                                 loc_vars_list.append(str(iecvar["NAME"]))
   816                                 loc_vars_list.append(str(iecvar["NAME"]))
   754                     client_requestid += 1
   817                     client_requestid += 1
   755                 rtuclient_node_count += 1
   818                 rtuclient_node_count += 1
   756                 client_nodeid += 1
   819                 client_nodeid += 1
   757             nodeid += 1
   820             nodeid += 1