Skip to content

Commit 3e6deb1

Browse files
committed
Extended script support, added script example project
1 parent 0b80b6e commit 3e6deb1

File tree

3 files changed

+120
-24
lines changed

3 files changed

+120
-24
lines changed

examples/server/test_script.pjs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project version="0.4.0" editnum="9">
3+
<name>TestScript</name>
4+
<author>serhmarch</author>
5+
<comment>Server project for script testing</comment>
6+
<ports>
7+
<port>
8+
<parity>No</parity>
9+
<name>PORT</name>
10+
<stopBits>1</stopBits>
11+
<flowControl>No</flowControl>
12+
<serialPortName>#TEST</serialPortName>
13+
<port>502</port>
14+
<timeoutFirstByte>1000</timeoutFirstByte>
15+
<dataBits>8</dataBits>
16+
<baudRate>9600</baudRate>
17+
<timeoutInterByte>50</timeoutInterByte>
18+
<host>localhost</host>
19+
<timeout>3000</timeout>
20+
<type>RTU</type>
21+
<deviceref>
22+
<deviceref name="PLC">1</deviceref>
23+
</deviceref>
24+
</port>
25+
</ports>
26+
<devices>
27+
<device>
28+
<byteArrayFormat>Hex</byteArrayFormat>
29+
<byteArraySeparator>\s</byteArraySeparator>
30+
<byteOrder>LessSignifiedFirst</byteOrder>
31+
<count0x>65535</count0x>
32+
<count1x>65534</count1x>
33+
<count3x>65533</count3x>
34+
<count4x>65532</count4x>
35+
<delay>0</delay>
36+
<exceptionStatusAddress>300001</exceptionStatusAddress>
37+
<isReadOnly>false</isReadOnly>
38+
<isSaveData>false</isSaveData>
39+
<maxReadCoils>2040</maxReadCoils>
40+
<maxReadDiscreteInputs>2040</maxReadDiscreteInputs>
41+
<maxReadHoldingRegisters>127</maxReadHoldingRegisters>
42+
<maxReadInputRegisters>127</maxReadInputRegisters>
43+
<maxWriteMultipleCoils>127</maxWriteMultipleCoils>
44+
<maxWriteMultipleRegisters>127</maxWriteMultipleRegisters>
45+
<name>PLC</name>
46+
<registerOrder>R0R1R2R3</registerOrder>
47+
<scriptInit># Objects for access corresponding device memory: mem0x, mem1x, mem3x, mem4x.
48+
#
49+
# Every object has set of get/set function to work with different data types:
50+
# * mem0x, mem1x: `get&lt;datatype&gt;(bitoffset:int)-&gt;(int, float)` and `set&lt;datatype&gt;(bitoffset:int,value:(int, float))`
51+
# * mem3x, mem4x: `get&lt;datatype&gt;(regoffset:int)-&gt;(int, float)` and `set&lt;datatype&gt;(regoffset:int,value:(int, float))`
52+
#
53+
# &lt;datatype&gt;: int8, uint8, int16, uint16, int32, uint32, int64, uint64, float, double.
54+
#
55+
# Examples:
56+
# v = mem0x.getint8(0)
57+
# mem1x.setint16(1, -1)
58+
# mem3x.setuint16(0, 65535)
59+
# mem3x.setfloat(0, 3.14)
60+
# mem4x.setdouble(10, 2.71828)
61+
62+
mems = (mem0x, mem1x, mem3x, mem4x)
63+
64+
lsoffset = [0,1,15,16,32,33,34,100]
65+
for mem in mems:
66+
print(f&quot;mem{mem.getid()}x test begins...&quot;)
67+
lsfunc = []
68+
lsfunc.append([mem.getint8 , mem.setint8 , -1])
69+
lsfunc.append([mem.getuint8 , mem.setuint8 , 0x81])
70+
lsfunc.append([mem.getint16 , mem.setint16 , -1])
71+
lsfunc.append([mem.getuint16, mem.setuint16, 0x8001])
72+
lsfunc.append([mem.getint32 , mem.setint32 , -1])
73+
lsfunc.append([mem.getuint32, mem.setuint32, 0x80000001])
74+
lsfunc.append([mem.getint64 , mem.setint64 , -1])
75+
lsfunc.append([mem.getuint64, mem.setuint64, 0x8000000000000001])
76+
77+
for getmethod, setmethod, value in lsfunc:
78+
for offset in lsoffset:
79+
setmethod(offset, value)
80+
if getmethod(offset) != value:
81+
print(f&quot;Error: mem{mem.getid()}x method ({str(setmethod)})&quot;)
82+
</scriptInit>
83+
<stringEncoding>UTF-8</stringEncoding>
84+
<stringLengthType>ZerroEnded</stringLengthType>
85+
</device>
86+
</devices>
87+
<windows>070000006465763a504c43000000003f030000000000003d0300005002000008000000696e69743a504c430800000000000000000000003f03000050020000</windows>
88+
</project>

src/server/python/mbServer.py

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ class _MbDevice:
4949
5050
More details.
5151
"""
52-
def __init__(self, memidprefix:str):
53-
memid_device = memidprefix + ".device"
54-
memid_python = memidprefix + ".python"
55-
memid_mem0x = memidprefix + ".mem0x"
56-
memid_mem1x = memidprefix + ".mem1x"
57-
memid_mem3x = memidprefix + ".mem3x"
58-
memid_mem4x = memidprefix + ".mem4x"
59-
shm = QSharedMemory(memid_device)
52+
def __init__(self, shmidprefix:str):
53+
shmid_device = shmidprefix + ".device"
54+
shmid_python = shmidprefix + ".python"
55+
shmid_mem0x = shmidprefix + ".mem0x"
56+
shmid_mem1x = shmidprefix + ".mem1x"
57+
shmid_mem3x = shmidprefix + ".mem3x"
58+
shmid_mem4x = shmidprefix + ".mem4x"
59+
shm = QSharedMemory(shmid_device)
6060
res = shm.attach()
6161
if not res:
62-
raise RuntimeError(f"Cannot attach to Shared Memory with id = '{memid_device}'")
62+
raise RuntimeError(f"Cannot attach to Shared Memory with id = '{shmid_device}'")
6363
qptr = shm.data()
6464
size = shm.size()
6565
memptr = c_void_p(qptr.__int__())
@@ -81,11 +81,11 @@ def __init__(self, memidprefix:str):
8181
self._name = self._getstring(stoDeviceName)
8282
self._shm.unlock()
8383
# submodules
84-
self._python = _MemoryPythonBlock(memid_python)
85-
self._mem0x = _MemoryBlockBits(memid_mem0x, self._count0x)
86-
self._mem1x = _MemoryBlockBits(memid_mem1x, self._count1x)
87-
self._mem3x = _MemoryBlockRegs(memid_mem3x, self._count3x)
88-
self._mem4x = _MemoryBlockRegs(memid_mem4x, self._count4x)
84+
self._python = _MemoryPythonBlock(shmid_python)
85+
self._mem0x = _MemoryBlockBits(shmid_mem0x, self._count0x, 0)
86+
self._mem1x = _MemoryBlockBits(shmid_mem1x, self._count1x, 1)
87+
self._mem3x = _MemoryBlockRegs(shmid_mem3x, self._count3x, 3)
88+
self._mem4x = _MemoryBlockRegs(shmid_mem4x, self._count4x, 4)
8989
# Exception status
9090
memtype = self._excstatusref // 100000
9191
self._excoffset = (self._excstatusref % 100000) - 1
@@ -233,11 +233,11 @@ def getmem4x(self):
233233

234234

235235
class _MemoryPythonBlock:
236-
def __init__(self, memid:str):
237-
shm = QSharedMemory(memid)
236+
def __init__(self, shmid:str):
237+
shm = QSharedMemory(shmid)
238238
res = shm.attach()
239239
if not res:
240-
raise RuntimeError(f"Cannot attach to Shared Memory with id = '{memid}'")
240+
raise RuntimeError(f"Cannot attach to Shared Memory with id = '{shmid}'")
241241
qptr = shm.data()
242242
self._memsize = shm.size()
243243
memptr = c_void_p(qptr.__int__())
@@ -272,17 +272,18 @@ class _MemoryBlock:
272272
273273
Class is abstract (can't be used directly).
274274
"""
275-
def __init__(self, memid:str, bytecount:int):
276-
shm = QSharedMemory(memid)
275+
def __init__(self, shmid:str, bytecount:int, id:int):
276+
shm = QSharedMemory(shmid)
277277
res = shm.attach()
278278
if not res:
279-
raise RuntimeError(f"Cannot attach to Shared Memory with id = '{memid}'")
279+
raise RuntimeError(f"Cannot attach to Shared Memory with id = '{shmid}'")
280280
qptr = shm.data()
281281
memptr = c_void_p(qptr.__int__())
282282
sz = shm.size()
283283
cbytes = bytecount if bytecount <= sz else sz
284284
self._shm = shm
285285
self._countbytes = cbytes
286+
self._id = id
286287
ptrhead = cast(memptr, POINTER(CMemoryBlockHeader))
287288
self._head = ptrhead[0]
288289
self._pmembytes = cast(byref(ptrhead[1]),POINTER(c_ubyte*1))
@@ -318,6 +319,12 @@ def _getbytes(self, byteoffset:int, count:int, bytestype=bytes)->bytes:
318319
return r
319320
return bytestype()
320321

322+
def getid(self)->int:
323+
"""
324+
@details Returns id (0, 1, 3 or 4) of the current memory object as integer.
325+
"""
326+
return self._id
327+
321328
def getbytes(self, byteoffset:int, count:int)->bytes:
322329
"""
323330
@details Function returns `bytes` object from device memory starting with `byteoffset` and `count` bytes.
@@ -525,8 +532,8 @@ class _MemoryBlockBits(_MemoryBlock):
525532
526533
More details.
527534
"""
528-
def __init__(self, memid:str, count:int):
529-
super().__init__(memid, (count+7)//8)
535+
def __init__(self, shmid:str, count:int, id:int):
536+
super().__init__(shmid, (count+7)//8, id)
530537
c = self._countbytes * 8
531538
self._count = count if count <= c else c
532539

@@ -877,8 +884,8 @@ class _MemoryBlockRegs(_MemoryBlock):
877884
878885
More details.
879886
"""
880-
def __init__(self, memid:str, count:int):
881-
super().__init__(memid, count*2)
887+
def __init__(self, shmid:str, count:int, id:int):
888+
super().__init__(shmid, count*2, id)
882889
c = self._countbytes // 2
883890
self._count = count if count <= c else c
884891
self._pmem = cast(self._pmembytes,POINTER(c_ushort*1))

src/server/resource/python/programhead.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/python
22

33
from os import sys, path
4+
from time import sleep
45
import argparse
56

67
_parser = argparse.ArgumentParser()

0 commit comments

Comments
 (0)