445 |
445 |
446 def GetConfigName(self): |
446 def GetConfigName(self): |
447 """ Return the node's Configuration_Name """ |
447 """ Return the node's Configuration_Name """ |
448 return self.ModbusServerNode.getConfiguration_Name() |
448 return self.ModbusServerNode.getConfiguration_Name() |
449 |
449 |
|
450 def GetVariableLocationTree(self): |
|
451 current_location = self.GetCurrentLocation() |
|
452 name = self.BaseParams.getName() |
|
453 # start off with flags that count the number of Modbus requests/transactions |
|
454 # handled by this Modbus server/slave. |
|
455 # These flags are mapped onto located variables and therefore available to the user programs |
|
456 # May be used to detect communication errors. |
|
457 # execute the Modbus request. |
|
458 # NOTE: If the Modbus slave has a 'current_location' of |
|
459 # %QX1.2 |
|
460 # then the "Modbus Read Request Counter" will be %MD1.2.0 |
|
461 # then the "Modbus Write Request Counter" will be %MD1.2.1 |
|
462 # then the "Modbus Read Request Flag" will be %MD1.2.2 |
|
463 # then the "Modbus Write Request Flag" will be %MD1.2.3 |
|
464 # |
|
465 # Note that any MemoryArea contained under this server/slave |
|
466 # will ocupy the locations of type |
|
467 # %MX or %MW |
|
468 # which will never clash with the %MD used here. |
|
469 # Additionaly, any MemoryArea contained under this server/slave |
|
470 # will ocupy locations with |
|
471 # %M1.2.a.b (with a and b being numbers in range 0, 1, ...) |
|
472 # and therefore never ocupy the locations |
|
473 # %M1.2.0 |
|
474 # %M1.2.1 |
|
475 # %M1.2.2 |
|
476 # %M1.2.3 |
|
477 # used by the following flags/counters. |
|
478 entries = [] |
|
479 entries.append({ |
|
480 "name": "Modbus Read Request Counter", |
|
481 "type": LOCATION_VAR_MEMORY, |
|
482 "size": 32, # UDINT flag |
|
483 "IEC_type": "UDINT", # UDINT flag |
|
484 "var_name": "var_name", |
|
485 "location": "D" + ".".join([str(i) for i in current_location]) + ".0", |
|
486 "description": "Modbus read request counter", |
|
487 "children": []}) |
|
488 entries.append({ |
|
489 "name": "Modbus Write Request Counter", |
|
490 "type": LOCATION_VAR_MEMORY, |
|
491 "size": 32, # UDINT flag |
|
492 "IEC_type": "UDINT", # UDINT flag |
|
493 "var_name": "var_name", |
|
494 "location": "D" + ".".join([str(i) for i in current_location]) + ".1", |
|
495 "description": "Modbus write request counter", |
|
496 "children": []}) |
|
497 entries.append({ |
|
498 "name": "Modbus Read Request Flag", |
|
499 "type": LOCATION_VAR_MEMORY, |
|
500 "size": 1, # BOOL flag |
|
501 "IEC_type": "BOOL", # BOOL flag |
|
502 "var_name": "var_name", |
|
503 "location": "X" + ".".join([str(i) for i in current_location]) + ".2", |
|
504 "description": "Modbus read request flag", |
|
505 "children": []}) |
|
506 entries.append({ |
|
507 "name": "Modbus write Request Flag", |
|
508 "type": LOCATION_VAR_MEMORY, |
|
509 "size": 1, # BOOL flag |
|
510 "IEC_type": "BOOL", # BOOL flag |
|
511 "var_name": "var_name", |
|
512 "location": "X" + ".".join([str(i) for i in current_location]) + ".3", |
|
513 "description": "Modbus write request flag", |
|
514 "children": []}) |
|
515 # recursively call all the Memory Areas under this Modbus server/save |
|
516 # i.e., all the children objects which will be of class _MemoryAreaPlug |
|
517 for child in self.IECSortedChildren(): |
|
518 entries.append(child.GetVariableLocationTree()) |
|
519 |
|
520 return {"name": name, |
|
521 "type": LOCATION_CONFNODE, |
|
522 "location": ".".join([str(i) for i in current_location]) + ".x", |
|
523 "children": entries} |
|
524 |
|
525 |
450 def CTNGenerate_C(self, buildpath, locations): |
526 def CTNGenerate_C(self, buildpath, locations): |
451 """ |
527 """ |
452 Generate C code |
528 Generate C code |
453 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
529 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
454 @param locations: List of complete variables locations \ |
530 @param locations: List of complete variables locations \ |
629 |
705 |
630 def GetConfigName(self): |
706 def GetConfigName(self): |
631 """ Return the node's Configuration_Name """ |
707 """ Return the node's Configuration_Name """ |
632 return self.ModbusRTUslave.getConfiguration_Name() |
708 return self.ModbusRTUslave.getConfiguration_Name() |
633 |
709 |
|
710 def GetVariableLocationTree(self): |
|
711 current_location = self.GetCurrentLocation() |
|
712 name = self.BaseParams.getName() |
|
713 # start off with flags that count the number of Modbus requests/transactions |
|
714 # handled by this Modbus server/slave. |
|
715 # These flags are mapped onto located variables and therefore available to the user programs |
|
716 # May be used to detect communication errors. |
|
717 # execute the Modbus request. |
|
718 # NOTE: If the Modbus slave has a 'current_location' of |
|
719 # %QX1.2 |
|
720 # then the "Modbus Read Request Counter" will be %MD1.2.0 |
|
721 # then the "Modbus Write Request Counter" will be %MD1.2.1 |
|
722 # then the "Modbus Read Request Flag" will be %MD1.2.2 |
|
723 # then the "Modbus Write Request Flag" will be %MD1.2.3 |
|
724 # |
|
725 # Note that any MemoryArea contained under this server/slave |
|
726 # will ocupy the locations of type |
|
727 # %MX or %MW |
|
728 # which will never clash with the %MD used here. |
|
729 # Additionaly, any MemoryArea contained under this server/slave |
|
730 # will ocupy locations with |
|
731 # %M1.2.a.b (with a and b being numbers in range 0, 1, ...) |
|
732 # and therefore never ocupy the locations |
|
733 # %M1.2.0 |
|
734 # %M1.2.1 |
|
735 # %M1.2.2 |
|
736 # %M1.2.3 |
|
737 # used by the following flags/counters. |
|
738 entries = [] |
|
739 entries.append({ |
|
740 "name": "Modbus Read Request Counter", |
|
741 "type": LOCATION_VAR_MEMORY, |
|
742 "size": 32, # UDINT flag |
|
743 "IEC_type": "UDINT", # UDINT flag |
|
744 "var_name": "var_name", |
|
745 "location": "D" + ".".join([str(i) for i in current_location]) + ".0", |
|
746 "description": "Modbus read request counter", |
|
747 "children": []}) |
|
748 entries.append({ |
|
749 "name": "Modbus Write Request Counter", |
|
750 "type": LOCATION_VAR_MEMORY, |
|
751 "size": 32, # UDINT flag |
|
752 "IEC_type": "UDINT", # UDINT flag |
|
753 "var_name": "var_name", |
|
754 "location": "D" + ".".join([str(i) for i in current_location]) + ".1", |
|
755 "description": "Modbus write request counter", |
|
756 "children": []}) |
|
757 entries.append({ |
|
758 "name": "Modbus Read Request Flag", |
|
759 "type": LOCATION_VAR_MEMORY, |
|
760 "size": 1, # BOOL flag |
|
761 "IEC_type": "BOOL", # BOOL flag |
|
762 "var_name": "var_name", |
|
763 "location": "X" + ".".join([str(i) for i in current_location]) + ".2", |
|
764 "description": "Modbus read request flag", |
|
765 "children": []}) |
|
766 entries.append({ |
|
767 "name": "Modbus write Request Flag", |
|
768 "type": LOCATION_VAR_MEMORY, |
|
769 "size": 1, # BOOL flag |
|
770 "IEC_type": "BOOL", # BOOL flag |
|
771 "var_name": "var_name", |
|
772 "location": "X" + ".".join([str(i) for i in current_location]) + ".3", |
|
773 "description": "Modbus write request flag", |
|
774 "children": []}) |
|
775 # recursively call all the Memory Areas under this Modbus server/save |
|
776 # i.e., all the children objects which will be of class _MemoryAreaPlug |
|
777 for child in self.IECSortedChildren(): |
|
778 entries.append(child.GetVariableLocationTree()) |
|
779 |
|
780 return {"name": name, |
|
781 "type": LOCATION_CONFNODE, |
|
782 "location": ".".join([str(i) for i in current_location]) + ".x", |
|
783 "children": entries} |
|
784 |
|
785 |
634 def CTNGenerate_C(self, buildpath, locations): |
786 def CTNGenerate_C(self, buildpath, locations): |
635 """ |
787 """ |
636 Generate C code |
788 Generate C code |
637 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
789 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
638 @param locations: List of complete variables locations \ |
790 @param locations: List of complete variables locations \ |
817 if child.PlugType == "ModbusTCPserver": |
969 if child.PlugType == "ModbusTCPserver": |
818 tcpserver_node_count += 1 |
970 tcpserver_node_count += 1 |
819 new_node = GetTCPServerNodePrinted(self, child) |
971 new_node = GetTCPServerNodePrinted(self, child) |
820 if new_node is None: |
972 if new_node is None: |
821 return [], "", False |
973 return [], "", False |
822 server_node_list.append(new_node) |
974 server_node_list.append(new_node) |
|
975 # We currently add 4 flags/counters to each Modbus server/slave |
823 # |
976 # |
|
977 # We add the Modbus read/write counter/flag to each Modbus slave/server |
|
978 # to allow the user program to determine if the slave is being actively |
|
979 # read from or written by by a remote Modbus client. |
|
980 for iecvar in child.GetLocations(): |
|
981 #print "child" + repr(iecvar) |
|
982 if (len(iecvar["LOC"]) == 3) and (str(iecvar["NAME"]) not in loc_vars_list): |
|
983 # Add if it is a "Modbus Read Request Counter" (mapped onto %MDa.b.0), so last number is a '0' |
|
984 if iecvar["LOC"][2] == 0: |
|
985 loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_counter;" % (server_id)) |
|
986 loc_vars_list.append(str(iecvar["NAME"])) |
|
987 # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.1), so last number is a '1' |
|
988 if iecvar["LOC"][2] == 1: |
|
989 loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_counter;" % (server_id)) |
|
990 loc_vars_list.append(str(iecvar["NAME"])) |
|
991 # Add if it is a "Modbus Read Request Flag" (mapped onto %MDa.b.2), so last number is a '2' |
|
992 if iecvar["LOC"][2] == 2: |
|
993 loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_flag;" % (server_id)) |
|
994 loc_vars_list.append(str(iecvar["NAME"])) |
|
995 # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.3), so last number is a '3' |
|
996 if iecvar["LOC"][2] == 3: |
|
997 loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_flag;" % (server_id)) |
|
998 loc_vars_list.append(str(iecvar["NAME"])) |
|
999 |
824 for subchild in child.IECSortedChildren(): |
1000 for subchild in child.IECSortedChildren(): |
825 new_memarea = GetTCPServerMemAreaPrinted( |
1001 new_memarea = GetTCPServerMemAreaPrinted(self, subchild, nodeid) |
826 self, subchild, nodeid) |
|
827 if new_memarea is None: |
1002 if new_memarea is None: |
828 return [], "", False |
1003 return [], "", False |
829 server_memarea_list.append(new_memarea) |
1004 server_memarea_list.append(new_memarea) |
830 function = subchild.GetParamsAttributes()[ |
1005 function = subchild.GetParamsAttributes()[0]["children"][0]["value"] |
831 0]["children"][0]["value"] |
|
832 # 'ro_bits', 'rw_bits', 'ro_words' or 'rw_words' |
1006 # 'ro_bits', 'rw_bits', 'ro_words' or 'rw_words' |
833 memarea = modbus_memtype_dict[function][1] |
1007 memarea = modbus_memtype_dict[function][1] |
834 for iecvar in subchild.GetLocations(): |
1008 for iecvar in subchild.GetLocations(): |
835 # print repr(iecvar) |
1009 if len(iecvar["LOC"]) == 4: |
836 absloute_address = iecvar["LOC"][3] |
1010 #print "subchild" + repr(iecvar) |
837 start_address = int(GetCTVal(subchild, 2)) |
1011 absloute_address = iecvar["LOC"][3] |
838 relative_addr = absloute_address - start_address |
1012 start_address = int(GetCTVal(subchild, 2)) |
839 # test if relative address in request specified range |
1013 relative_addr = absloute_address - start_address |
840 if relative_addr in xrange(int(GetCTVal(subchild, 1))): |
1014 # test if relative address in request specified range |
841 if str(iecvar["NAME"]) not in loc_vars_list: |
1015 if relative_addr in xrange(int(GetCTVal(subchild, 1))): |
842 loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % ( |
1016 if str(iecvar["NAME"]) not in loc_vars_list: |
843 server_id, memarea, absloute_address)) |
1017 loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % ( |
844 loc_vars_list.append(str(iecvar["NAME"])) |
1018 server_id, memarea, absloute_address)) |
|
1019 loc_vars_list.append(str(iecvar["NAME"])) |
845 server_id += 1 |
1020 server_id += 1 |
846 # |
1021 # |
847 if child.PlugType == "ModbusRTUslave": |
1022 if child.PlugType == "ModbusRTUslave": |
848 rtuserver_node_count += 1 |
1023 rtuserver_node_count += 1 |
849 new_node = GetRTUSlaveNodePrinted(self, child) |
1024 new_node = GetRTUSlaveNodePrinted(self, child) |
850 if new_node is None: |
1025 if new_node is None: |
851 return [], "", False |
1026 return [], "", False |
852 server_node_list.append(new_node) |
1027 server_node_list.append(new_node) |
|
1028 # We currently add 4 flags/counters to each Modbus server/slave |
853 # |
1029 # |
|
1030 # We add the Modbus read/write counter/flag to each Modbus slave/server |
|
1031 # to allow the user program to determine if the slave is being actively |
|
1032 # read from or written by by a remote Modbus client. |
|
1033 for iecvar in child.GetLocations(): |
|
1034 #print "child" + repr(iecvar) |
|
1035 if (len(iecvar["LOC"]) == 3) and (str(iecvar["NAME"]) not in loc_vars_list): |
|
1036 # Add if it is a "Modbus Read Request Counter" (mapped onto %MDa.b.0), so last number is a '0' |
|
1037 if iecvar["LOC"][2] == 0: |
|
1038 loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_counter;" % (server_id)) |
|
1039 loc_vars_list.append(str(iecvar["NAME"])) |
|
1040 # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.1), so last number is a '1' |
|
1041 if iecvar["LOC"][2] == 1: |
|
1042 loc_vars.append("u32 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_counter;" % (server_id)) |
|
1043 loc_vars_list.append(str(iecvar["NAME"])) |
|
1044 # Add if it is a "Modbus Read Request Flag" (mapped onto %MDa.b.2), so last number is a '2' |
|
1045 if iecvar["LOC"][2] == 2: |
|
1046 loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_read_req_flag;" % (server_id)) |
|
1047 loc_vars_list.append(str(iecvar["NAME"])) |
|
1048 # Add if it is a "Modbus Write Request Counter" (mapped onto %MDa.b.3), so last number is a '3' |
|
1049 if iecvar["LOC"][2] == 3: |
|
1050 loc_vars.append("u8 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.flag_write_req_flag;" % (server_id)) |
|
1051 loc_vars_list.append(str(iecvar["NAME"])) |
|
1052 |
854 for subchild in child.IECSortedChildren(): |
1053 for subchild in child.IECSortedChildren(): |
855 new_memarea = GetTCPServerMemAreaPrinted( |
1054 new_memarea = GetTCPServerMemAreaPrinted( |
856 self, subchild, nodeid) |
1055 self, subchild, nodeid) |
857 if new_memarea is None: |
1056 if new_memarea is None: |
858 return [], "", False |
1057 return [], "", False |
859 server_memarea_list.append(new_memarea) |
1058 server_memarea_list.append(new_memarea) |
860 function = subchild.GetParamsAttributes()[ |
1059 function = subchild.GetParamsAttributes()[0]["children"][0]["value"] |
861 0]["children"][0]["value"] |
|
862 # 'ro_bits', 'rw_bits', 'ro_words' or 'rw_words' |
1060 # 'ro_bits', 'rw_bits', 'ro_words' or 'rw_words' |
863 memarea = modbus_memtype_dict[function][1] |
1061 memarea = modbus_memtype_dict[function][1] |
864 for iecvar in subchild.GetLocations(): |
1062 for iecvar in subchild.GetLocations(): |
865 # print repr(iecvar) |
1063 if len(iecvar["LOC"]) == 4: |
866 absloute_address = iecvar["LOC"][3] |
1064 # print repr(iecvar) |
867 start_address = int(GetCTVal(subchild, 2)) |
1065 absloute_address = iecvar["LOC"][3] |
868 relative_addr = absloute_address - start_address |
1066 start_address = int(GetCTVal(subchild, 2)) |
869 # test if relative address in request specified range |
1067 relative_addr = absloute_address - start_address |
870 if relative_addr in xrange(int(GetCTVal(subchild, 1))): |
1068 # test if relative address in request specified range |
871 if str(iecvar["NAME"]) not in loc_vars_list: |
1069 if relative_addr in xrange(int(GetCTVal(subchild, 1))): |
872 loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % ( |
1070 if str(iecvar["NAME"]) not in loc_vars_list: |
873 server_id, memarea, absloute_address)) |
1071 loc_vars.append("u16 *" + str(iecvar["NAME"]) + " = &server_nodes[%d].mem_area.%s[%d];" % ( |
874 loc_vars_list.append(str(iecvar["NAME"])) |
1072 server_id, memarea, absloute_address)) |
|
1073 loc_vars_list.append(str(iecvar["NAME"])) |
875 server_id += 1 |
1074 server_id += 1 |
876 # |
1075 # |
877 if child.PlugType == "ModbusTCPclient": |
1076 if child.PlugType == "ModbusTCPclient": |
878 tcpclient_reqs_count += len(child.IECSortedChildren()) |
1077 tcpclient_reqs_count += len(child.IECSortedChildren()) |
879 new_node = GetTCPClientNodePrinted(self, child) |
1078 new_node = GetTCPClientNodePrinted(self, child) |