|
| 1 | +import ctypes |
| 2 | +import struct |
1 | 3 | import unittest |
2 | 4 | import logging |
3 | 5 | import time |
4 | 6 | from subprocess import Popen |
5 | 7 | from os import path, kill |
6 | 8 | import snap7 |
7 | 9 | from snap7.snap7exceptions import Snap7Exception |
| 10 | +from snap7.snap7types import S7AreaDB, S7WLByte, S7DataItem |
8 | 11 |
|
9 | 12 |
|
10 | 13 | logging.basicConfig(level=logging.WARNING) |
@@ -54,6 +57,75 @@ def test_db_write(self): |
54 | 57 | def test_db_get(self): |
55 | 58 | self.client.db_get(db_number=db_number) |
56 | 59 |
|
| 60 | + def test_read_multi_vars(self): |
| 61 | + db = 1 |
| 62 | + |
| 63 | + # build and write test values |
| 64 | + test_value_1 = 129.5 |
| 65 | + test_bytes_1 = bytearray(struct.pack('>f', test_value_1)) |
| 66 | + self.client.db_write(db, 0, test_bytes_1) |
| 67 | + |
| 68 | + test_value_2 = -129.5 |
| 69 | + test_bytes_2 = bytearray(struct.pack('>f', test_value_2)) |
| 70 | + self.client.db_write(db, 4, test_bytes_2) |
| 71 | + |
| 72 | + test_value_3 = -123 |
| 73 | + test_bytes_3 = bytearray(struct.pack('>h', test_value_3)) |
| 74 | + self.client.db_write(db, 8, test_bytes_3) |
| 75 | + |
| 76 | + test_values = [test_value_1, test_value_2, test_value_3] |
| 77 | + |
| 78 | + # build up our requests |
| 79 | + data_items = (S7DataItem * 3)() |
| 80 | + |
| 81 | + data_items[0].Area = ctypes.c_int32(S7AreaDB) |
| 82 | + data_items[0].WordLen = ctypes.c_int32(S7WLByte) |
| 83 | + data_items[0].Result = ctypes.c_int32(0) |
| 84 | + data_items[0].DBNumber = ctypes.c_int32(db) |
| 85 | + data_items[0].Start = ctypes.c_int32(0) |
| 86 | + data_items[0].Amount = ctypes.c_int32(4) # reading a REAL, 4 bytes |
| 87 | + |
| 88 | + data_items[1].Area = ctypes.c_int32(S7AreaDB) |
| 89 | + data_items[1].WordLen = ctypes.c_int32(S7WLByte) |
| 90 | + data_items[1].Result = ctypes.c_int32(0) |
| 91 | + data_items[1].DBNumber = ctypes.c_int32(db) |
| 92 | + data_items[1].Start = ctypes.c_int32(4) |
| 93 | + data_items[1].Amount = ctypes.c_int32(4) # reading a REAL, 4 bytes |
| 94 | + |
| 95 | + data_items[2].Area = ctypes.c_int32(S7AreaDB) |
| 96 | + data_items[2].WordLen = ctypes.c_int32(S7WLByte) |
| 97 | + data_items[2].Result = ctypes.c_int32(0) |
| 98 | + data_items[2].DBNumber = ctypes.c_int32(db) |
| 99 | + data_items[2].Start = ctypes.c_int32(8) |
| 100 | + data_items[2].Amount = ctypes.c_int32(2) # reading an INT, 2 bytes |
| 101 | + |
| 102 | + # create buffers to receive the data |
| 103 | + # use the Amount attribute on each item to size the buffer |
| 104 | + for di in data_items: |
| 105 | + # create the buffer |
| 106 | + dataBuffer = ctypes.create_string_buffer(di.Amount) |
| 107 | + # get a pointer to the buffer |
| 108 | + pBuffer = ctypes.cast(ctypes.pointer(dataBuffer), |
| 109 | + ctypes.POINTER(ctypes.c_uint8)) |
| 110 | + di.pData = pBuffer |
| 111 | + |
| 112 | + result, data_items = self.client.read_multi_vars(data_items) |
| 113 | + |
| 114 | + result_values = [] |
| 115 | + # struct formats to match data_items[] above |
| 116 | + fmts = ['>f', '>f', '>h'] |
| 117 | + # unpack and test the result of each read |
| 118 | + for i in xrange(0, len(data_items)): |
| 119 | + fmt = fmts[i] |
| 120 | + di = data_items[i] |
| 121 | + bytes_str = ''.join([chr(di.pData[j]) for j in range(0, di.Amount)]) |
| 122 | + result_values.append(struct.unpack(fmt, bytes_str)[0]) |
| 123 | + |
| 124 | + self.assertEqual(result_values[0], test_values[0]) |
| 125 | + self.assertEqual(result_values[1], test_values[1]) |
| 126 | + self.assertEqual(result_values[2], test_values[2]) |
| 127 | + |
| 128 | + |
57 | 129 | def test_upload(self): |
58 | 130 | """ |
59 | 131 | this raises an exception due to missing authorization? maybe not |
|
0 commit comments