def write_value(data_type, result, data, byte_index=0, bool_index=0): # 'FLOAT' if data_type == 1: set_real(result, byte_index, data) # 'INT' elif data_type == 2: set_int(result, byte_index, data) # 'DINT' elif data_type == 3: set_dint(result, byte_index, data) # 'WORD' elif data_type == 4: set_word(result, byte_index, data) # 'DWORD' elif data_type == 5: set_dword(result, byte_index, data) # 'BYTE' elif data_type == 6: set_byte(result, byte_index, data) # 'BOOL' elif data_type == 7: set_bool(result, byte_index, bool_index, data)
def test_set_int_roundtrip(self): DB1 = (types.wordlen_to_ctypes[types.S7WLByte] * 4)() for i in range(-(2 ** 15) + 1, (2 ** 15) - 1): util.set_int(DB1, 0, i) result = util.get_int(DB1, 0) self.assertEqual(i, result)
def write(self,datatype,*args): self.pc2plc_data=self.plc.db_read(self.db_number,self.db_write_start,self.db_write_size) if datatype=='bool': util.set_bool(self.pc2plc_data,args[0],args[1],args[2]) elif datatype=='int': util.set_int(self.pc2plc_data,args[0],args[1]) elif datatype==('dint' or 'dword'): util.set_dword(self.pc2plc_data,args[0],args[1]) elif datatype=='real': util.set_real(self.pc2plc_data,args[0],args[1]) elif datatype=='string': util.set_string(self.pc2plc_data,args[0],args[1],args[2]) self.plc.db_write(self.db_number,self.db_write_start,self.pc2plc_data)
def write_value(data_type, result, data, byte_index=0, bool_index=0): if data_type == 'FLOAT': set_real(result, byte_index, data) elif data_type == 'INT': set_int(result, byte_index, data) elif data_type == 'DINT': set_dint(result, byte_index, data) elif data_type == 'WORD': set_word(result, byte_index, data) elif data_type == 'BYTE': set_byte(result, byte_index, data) elif data_type == 'BOOL': set_bool(result, byte_index, bool_index, data) elif data_type == 'DWORD': set_dword(result, byte_index, data)
def writeInt(self, area, dbnumber, start, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.plc is not None and self.plc.get_connected(): with suppress_stdout_stderr(): ba = self.plc.read_area(self.areas[area], dbnumber, start, 2) from snap7.util import set_int set_int(ba, 0, int(value)) self.plc.write_area(self.areas[area], dbnumber, start, ba) else: self.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception: self.adderror( QApplication.translate("Error Message", "S7 Communication Error", None)) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1)
def create_bytearray(size, lst): """ Create bytearray for plc :param size: int :param lst: list :return holder: bytearray :raises TypeError plc_exception.DatabaseError """ if not isinstance(lst, list): raise TypeError("create_bytearray takes list.") lst = sorted(lst, key=lambda x: x['Offset']) holder = bytearray([0 for _ in range(size)]) for foo in lst: _offset = foo["Offset"] _value = foo["Value"] if foo['Data_type'] == 'Bool': byte, bit = str(float(_offset)).split('.') byte, bit = int(byte), int(bit) set_bool(holder, byte, bit, _value) elif foo['Data_type'] == 'String': set_string(holder, int(_offset), _value, 256) elif foo['Data_type'] == 'Int': set_int(holder, int(_offset), _value) elif foo['Data_type'] == 'Real': set_real(holder, int(_offset), _value) else: raise plc_exception.DatabaseError("Data is not correct.") return holder
def test_read_multi_vars(self): db = 1 # build and write test values test_value_1 = 129.5 test_bytes_1 = bytearray(struct.pack('>f', test_value_1)) self.client.db_write(db, 0, test_bytes_1) test_value_2 = -129.5 test_bytes_2 = bytearray(struct.pack('>f', test_value_2)) self.client.db_write(db, 4, test_bytes_2) test_value_3 = 123 test_bytes_3 = bytearray([0, 0]) util.set_int(test_bytes_3, 0, test_value_3) self.client.db_write(db, 8, test_bytes_3) test_values = [test_value_1, test_value_2, test_value_3] # build up our requests data_items = (S7DataItem * 3)() data_items[0].Area = ctypes.c_int32(S7AreaDB) data_items[0].WordLen = ctypes.c_int32(S7WLByte) data_items[0].Result = ctypes.c_int32(0) data_items[0].DBNumber = ctypes.c_int32(db) data_items[0].Start = ctypes.c_int32(0) data_items[0].Amount = ctypes.c_int32(4) # reading a REAL, 4 bytes data_items[1].Area = ctypes.c_int32(S7AreaDB) data_items[1].WordLen = ctypes.c_int32(S7WLByte) data_items[1].Result = ctypes.c_int32(0) data_items[1].DBNumber = ctypes.c_int32(db) data_items[1].Start = ctypes.c_int32(4) data_items[1].Amount = ctypes.c_int32(4) # reading a REAL, 4 bytes data_items[2].Area = ctypes.c_int32(S7AreaDB) data_items[2].WordLen = ctypes.c_int32(S7WLByte) data_items[2].Result = ctypes.c_int32(0) data_items[2].DBNumber = ctypes.c_int32(db) data_items[2].Start = ctypes.c_int32(8) data_items[2].Amount = ctypes.c_int32(2) # reading an INT, 2 bytes # create buffers to receive the data # use the Amount attribute on each item to size the buffer for di in data_items: # create the buffer dataBuffer = ctypes.create_string_buffer(di.Amount) # get a pointer to the buffer pBuffer = ctypes.cast(ctypes.pointer(dataBuffer), ctypes.POINTER(ctypes.c_uint8)) di.pData = pBuffer result, data_items = self.client.read_multi_vars(data_items) result_values = [] # function to cast bytes to match data_types[] above byte_to_value = [util.get_real, util.get_real, util.get_int] # unpack and test the result of each read for i in range(0, len(data_items)): btv = byte_to_value[i] di = data_items[i] value = btv(di.pData, 0) result_values.append(value) self.assertEqual(result_values[0], test_values[0]) self.assertEqual(result_values[1], test_values[1]) self.assertEqual(result_values[2], test_values[2])
item = S7DataItem() item.Area = ctypes.c_int32(area) item.WordLen = ctypes.c_int32(word_len) item.DBNumber = ctypes.c_int32(db_number) item.Start = ctypes.c_int32(start) item.Amount = ctypes.c_int32(amount) array_class = ctypes.c_uint8 * len(data) cdata = array_class.from_buffer_copy(data) item.pData = ctypes.cast(cdata, ctypes.POINTER(array_class)).contents return item int_values = [10, 20, 30, 40] ints = bytearray(len(int_values) * 2) for i, value in enumerate(int_values): set_int(ints, i * 2, value) real = bytearray(4) set_real(real, 0, 42.5) counters = 0x2999.to_bytes(2, 'big') + 0x1111.to_bytes(2, 'big') item1 = set_data_item(area=Areas.DB, word_len=S7WLWord, db_number=1, start=0, amount=4, data=ints) item2 = set_data_item(area=Areas.DB, word_len=S7WLReal, db_number=1,
def test_read_multi_vars(self): db = 1 # build and write test values test_value_1 = 129.5 test_bytes_1 = bytearray(struct.pack('>f', test_value_1)) self.client.db_write(db, 0, test_bytes_1) test_value_2 = -129.5 test_bytes_2 = bytearray(struct.pack('>f', test_value_2)) self.client.db_write(db, 4, test_bytes_2) test_value_3 = 123 test_bytes_3 = bytearray([0, 0]) util.set_int(test_bytes_3, 0, test_value_3) self.client.db_write(db, 8, test_bytes_3) test_values = [test_value_1, test_value_2, test_value_3] # build up our requests data_items = (S7DataItem * 3)() data_items[0].Area = ctypes.c_int32(S7AreaDB) data_items[0].WordLen = ctypes.c_int32(S7WLByte) data_items[0].Result = ctypes.c_int32(0) data_items[0].DBNumber = ctypes.c_int32(db) data_items[0].Start = ctypes.c_int32(0) data_items[0].Amount = ctypes.c_int32(4) # reading a REAL, 4 bytes data_items[1].Area = ctypes.c_int32(S7AreaDB) data_items[1].WordLen = ctypes.c_int32(S7WLByte) data_items[1].Result = ctypes.c_int32(0) data_items[1].DBNumber = ctypes.c_int32(db) data_items[1].Start = ctypes.c_int32(4) data_items[1].Amount = ctypes.c_int32(4) # reading a REAL, 4 bytes data_items[2].Area = ctypes.c_int32(S7AreaDB) data_items[2].WordLen = ctypes.c_int32(S7WLByte) data_items[2].Result = ctypes.c_int32(0) data_items[2].DBNumber = ctypes.c_int32(db) data_items[2].Start = ctypes.c_int32(8) data_items[2].Amount = ctypes.c_int32(2) # reading an INT, 2 bytes # create buffers to receive the data # use the Amount attribute on each item to size the buffer for di in data_items: # create the buffer dataBuffer = ctypes.create_string_buffer(di.Amount) # get a pointer to the buffer pBuffer = ctypes.cast(ctypes.pointer(dataBuffer), ctypes.POINTER(ctypes.c_uint8)) di.pData = pBuffer result, data_items = self.client.read_multi_vars(data_items) result_values = [] # function to cast bytes to match data_types[] above byte_to_value = [util.get_real, util.get_real, util.get_int] # unpack and test the result of each read for i in range(0, len(data_items)): btv = byte_to_value[i] di = data_items[i] value = btv(di.pData, 0) result_values.append(value) self.assertEqual(result_values[0], test_values[0]) self.assertEqual(result_values[1], test_values[1]) self.assertEqual(result_values[2], test_values[2])
size = SIZE globaldata = (wordlen_to_ctypes[S7WLByte]*size)() outputs = (wordlen_to_ctypes[S7WLByte]*size)() inputs = (wordlen_to_ctypes[S7WLByte]*size)() dbs = (wordlen_to_ctypes[S7WLByte]*size)() server.register_area(srvAreaPA, 0, outputs) server.register_area(srvAreaMK, 0, globaldata) server.register_area(srvAreaPE, 0, inputs) server.register_area(srvAreaDB, 0, dbs) server.start(tcpport=PORT) util.set_real(outputs, 0, 1.234) # srvAreaPA util.set_real(globaldata, 0, 2.234) # srvAreaMK util.set_real(inputs, 0, 3.234) # srvAreaPE util.set_real(dbs, 0, 31.1) util.set_bool(dbs, 5, 0, True) util.set_bool(dbs, 5, 1, True) util.set_int(dbs, 6, 12323) while True: while True: event = server.pick_event() if event: print (server.event_text(event)) else: break time.sleep(.01) server.stop() server.destroy()
import snap7 from snap7.snap7exceptions import Snap7Exception from snap7.snap7types import S7AreaDB, S7WLByte, S7DataItem from snap7.util import set_int import struct import snap7 from snap7.snap7types import S7AreaDB, S7AreaMK snap7.common.load_library( lib_location=path.join(path.abspath(path.dirname(__file__)), "plc_connect_lib/snap7/mac_os/libsnap7.dylib")) # server_path = path.join(path.abspath(path.dirname(__file__)), # "plc_connect_lib/python-snap7/snap7/bin/snap7-server.py") # server_pid = Popen([server_path]).pid # time.sleep(2) # wait for server to start client = snap7.client.Client() # client.connect('192.168.18.12', 0, 2, 102) client.connect('127.0.0.1', 1, 1, 1102) client.db_rea a = client.read_area(S7AreaDB, 1, 0, 2) set_int(a, 0, 2) client.write_area(S7AreaDB, 1, 0, a) a = client.read_area(S7AreaDB, 1, 0, 2) data = struct.unpack('!h', a)[0] print(data) # kill(server_pid, 1)