Projekt

Obecné

Profil

Stáhnout (11.4 KB) Statistiky
| Větev: | Tag: | Revize:
1
#!/usr/bin/env python
2
"""
3
Pymodbus Server With Updating Thread
4
--------------------------------------------------------------------------
5

    
6
This is an example of having a background thread updating the
7
context while the server is operating. This can also be done with
8
a python thread::
9

    
10
    from threading import Thread
11

    
12
    thread = Thread(target=updating_writer, args=(context,))
13
    thread.start()
14
"""
15
# --------------------------------------------------------------------------- #
16
# import the modbus libraries we need
17
# --------------------------------------------------------------------------- #
18
from pymodbus.server.asynchronous import StartTcpServer
19
from pymodbus.device import ModbusDeviceIdentification
20
from pymodbus.datastore import ModbusSequentialDataBlock
21
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
22

    
23
# --------------------------------------------------------------------------- #
24
# import the twisted libraries we need
25
# --------------------------------------------------------------------------- #
26
from twisted.internet.task import LoopingCall
27

    
28
# --------------------------------------------------------------------------- #
29
# configure the service logging
30
# --------------------------------------------------------------------------- #
31
import logging
32
logging.basicConfig()
33
log = logging.getLogger()
34
log.setLevel(logging.ERROR)
35

    
36
# random numbers
37
import random
38

    
39
# global constants
40

    
41
# discrete input
42
# poloha klicku
43
BIT_BKEY = 32789
44
# bezpecnostni tlacitko
45
BIT_SAFETY_BTN = 32785
46

    
47
# holding regs
48
# aktualni poloha
49
REG_X = 32768
50
REG_Y = 32769
51
REG_Z = 32770
52
REG_A = 32771
53
#pozice vektoru, kam se tlaci
54
REG_ACT_X = 32772
55
REG_ACT_Y = 32773
56
REG_ACT_Z = 32774
57
#pozice vektoru, kam se ma tlacit
58
REG_DIR_X = 32776
59
REG_DIR_Y = 32777
60
REG_DIR_Z = 32778
61

    
62
#data s krivkou
63
REG_INDEX = 32867
64
REG_LEN = 32866
65
REG_DATA = 32868
66
# data s kvalitou cviceni
67
REG_Q_1 = 32780
68
REG_Q_TOT = 32781
69
REG_Q_PART = 32782
70

    
71
#coils
72
#info bity 
73
BIT_RDY = 32871
74
BIT_PC_TO_PLC = 32869
75
BIT_PLC_TO_PC = 32870
76
BIT_MEASUREMENT_TO_PC = 32874
77
#posun motoru
78
BIT_M_UP = 32788
79
BIT_M_DOWN = 32789
80
# uceni
81
BIT_TEACH = 32780
82
# reset pozice
83
BIT_RESET_POS = 32769
84
# prehravani naucene krivky
85
BIT_BPLAY = 32772
86
#cviceni naucene kriky
87
BIT_BPLAY_ASSIST = 32773
88
#priznak ukonceni jednoho cyklu
89
BIT_PART_FINISHED = 32873
90
#adresy pro testovaci zmenu DI
91
BIT_BKEY_CHANGE = 32950
92
BIT_SBTN_CHANGE = 32951
93
#test stop coil
94
BIT_STOP = 32838
95

    
96
# modbus reg
97
MB_CO = 1
98
MB_DI = 2
99
MB_HR = 3
100
MB_IR = 4
101

    
102
# --------------------------------------------------------------------------- #
103
# define your callback process
104
# --------------------------------------------------------------------------- #
105
def prepareMbRegVals(values):
106
    vals = []
107
    for val in values:
108
        if val < 0:
109
            val = val & 0xFFFF
110
        vals.append(val)
111
    return vals
112

    
113
def updating_writer(a,):
114
    """ A worker process that runs every so often and
115
    updates live values of the context. It should be noted
116
    that there is a race condition for the update.
117

    
118
    :param arguments: The input arguments to the call
119
    """
120
    global bit_teach, bit_play, bit_rdy, bit_data_change, bit_motor, learned_curve, index_curve, meas_array
121
    global cycles_no, quality, array_pos
122

    
123
    reset_pos = [0,0,4000]
124
    
125
    log.debug("updating the context")
126
    context = a[0]
127
    
128
    
129
    brdy = context[0].getValues(MB_CO, BIT_RDY, 1)
130
    data_change = context[0].getValues(MB_CO, BIT_PC_TO_PLC, 2)
131
    measurement_get = context[0].getValues(MB_CO, BIT_MEASUREMENT_TO_PC, 1)
132
    motor = context[0].getValues(MB_CO, BIT_M_UP, 2)
133
    bteach = context[0].getValues(MB_CO, BIT_TEACH, 1)
134
    bplay = context[0].getValues(MB_CO, BIT_BPLAY, 2)
135

    
136
    if (context[0].getValues(MB_CO, BIT_RESET_POS, 1) == [1]):
137
        print("Position reset")
138
        context[0].setValues(MB_CO, BIT_RESET_POS, [0])
139
        context[0].setValues(MB_HR, REG_X, reset_pos)
140
    if (bteach != bit_teach):
141
        if (bteach == [1]):
142
            bplay = [0, 0]
143
            context[0].setValues(MB_CO, BIT_BPLAY, bplay)
144
            learned_curve = []
145
            array_pos = 0
146
            f = open("curve.txt")
147
            for line in f:
148
                line.rstrip()
149
                lineStr = line.split(";")
150
                onePoint = [int(i) for i in lineStr]
151
                learned_curve.extend(prepareMbRegVals(onePoint))
152
                print(onePoint)
153
            print(len(learned_curve)//4)
154
        else:
155
            index_curve = 0
156
    if (motor != bit_motor):
157
        if (motor[0] == 1):
158
            context[0].setValues(MB_CO, BIT_STOP, [1])
159
            print("Up")
160
        elif (motor[1] == 1):
161
            context[0].setValues(MB_CO, BIT_STOP, [1])
162
            print("Down")
163
        else:
164
            context[0].setValues(MB_CO, BIT_STOP, [0])
165
            print("Stop")
166
    if (bit_data_change != data_change):
167
        if (data_change == [0,0]):
168
            brdy = [0]
169
            context[0].setValues(MB_CO, BIT_RDY, brdy)
170
    if (data_change[0] == 1):
171
        if (bit_rdy != brdy) and (brdy == [1]):
172
            val = context[0].getValues(MB_HR, REG_LEN, 2)
173
            print("<- Len: " + str(val[0]) + ", Index: " + str(val[1]))
174
            points = val[0]-val[1]
175
            if (points > 25):
176
                points = 25
177
            learned_curve.extend(context[0].getValues(MB_HR, REG_DATA, points*4))
178
            brdy = [0]
179
            context[0].setValues(MB_CO, BIT_RDY, brdy)
180
    if (data_change[0] != bit_data_change[0]):
181
        if (data_change[0] == 0):
182
            index_curve = 0
183
            print("curve finish")
184
        else:
185
            bplay = [0, 0]
186
            context[0].setValues(MB_CO, BIT_BPLAY, bplay)
187
            learned_curve = []
188
    if (data_change[1] == 1):
189
        if (brdy == [0]):
190
            index_to = index_curve + 25
191
            if (len(learned_curve)-(index_curve*4) < 100):
192
                index_to = len(learned_curve)//4
193
            context[0].setValues(MB_HR, REG_DATA, learned_curve[index_curve*4:index_to*4])
194
            brdy = [1]
195
            context[0].setValues(MB_HR, REG_LEN, [len(learned_curve)//4])
196
            context[0].setValues(MB_HR, REG_INDEX, [index_curve])
197
            context[0].setValues(MB_CO, BIT_RDY, brdy)
198
            print("-> Len: " + str(len(learned_curve)) + ", Index: " + str(index_curve) + ", to: " + str(index_to))
199
            index_curve += 25
200
            if (index_curve*4 > len(learned_curve)):
201
                context[0].setValues(MB_CO, BIT_PLC_TO_PC, [0])
202
                index_curve = 0
203
    if (measurement_get == [1]):
204
        if (brdy == [0]):
205
            index_to = index_curve + 10
206
            if (len(meas_array)-(index_curve*10) < 100):
207
                index_to = len(meas_array)//10
208
            context[0].setValues(MB_HR, REG_DATA, meas_array[index_curve*10:index_to*10])
209
            brdy = [1]
210
            context[0].setValues(MB_HR, REG_LEN, [len(meas_array)//10])
211
            context[0].setValues(MB_HR, REG_INDEX, [index_curve])
212
            context[0].setValues(MB_CO, BIT_RDY, brdy)
213
            print("-> Len: " + str(len(meas_array)) + ", Index: " + str(index_curve) + ", to: " + str(index_to))
214
            index_curve += 10
215
            if (index_curve*10 > len(learned_curve)):
216
                context[0].setValues(MB_CO, BIT_MEASUREMENT_TO_PC, [0])
217
                index_curve = 0
218
            print("measure")
219
    if (bplay != bit_play):
220
        cycles_no = 0
221
        array_pos = 0
222
        quality = [0,0,0]
223
    if (bit_play[1] == 1):
224
        onePoint = learned_curve[array_pos*4:array_pos*4+3]
225
        context[0].setValues(MB_HR, REG_X, onePoint)
226
        
227
        values = [random.randint(-500,500),random.randint(-500,500),random.randint(-200,200),0]
228
        onePoint = prepareMbRegVals(values)
229
        context[0].setValues(MB_HR, REG_ACT_X, onePoint)
230
        values = [random.randint(-200,200),random.randint(-200,200),random.randint(-70,70),0]
231
        onePoint = prepareMbRegVals(values)
232
        context[0].setValues(MB_HR, REG_DIR_X, onePoint)
233
        cycles_no += 1
234
        array_pos += 3
235
        if (array_pos*4 > len(learned_curve)):
236
            array_pos = 0
237
        if (array_pos == 0):
238
            quality[0] = (random.randint(45,100));
239
            context[0].setValues(MB_CO, BIT_PART_FINISHED, [1])
240
        if (cycles_no%25 == 0):
241
            quality[1] = (random.randint(45,100));
242
        quality[2] = (random.randint(45,100));
243
        context[0].setValues(MB_HR, REG_Q_1, quality)
244
    else:
245
        if (bteach == [1]):
246
            #learned_curve.extend(onePoint);
247
            onePoint = learned_curve[array_pos*4:array_pos*4+4]
248
            context[0].setValues(MB_HR, REG_X, onePoint)
249
            array_pos += 8
250
            if (array_pos > len(learned_curve)//4):
251
                context[0].setValues(MB_CO, BIT_TEACH, [0])
252
        else:
253
            values = [random.randint(-1000,1000),random.randint(-1000,1000),random.randint(5000,8000),0]
254
            onePoint = prepareMbRegVals(values)
255
            context[0].setValues(MB_HR, REG_X, onePoint)
256
            context[0].setValues(MB_HR, REG_X, reset_pos)
257
    
258
    #test: set input register using testing coils
259
    #bkey_change = context[0].getValues(MB_CO, BIT_BKEY_CHANGE, 2)
260
    bkey_change = [1,1]
261
    context[0].setValues(MB_DI, BIT_BKEY, [bkey_change[0]])
262
    context[0].setValues(MB_DI, BIT_SAFETY_BTN, [bkey_change[1]])
263
        
264
    bit_rdy = brdy
265
    bit_data_change = data_change
266
    bit_motor = motor
267
    bit_teach = bteach
268
    bit_play = bplay
269

    
270
def run_updating_server():
271
    # ----------------------------------------------------------------------- # 
272
    # initialize your data store
273
    # ----------------------------------------------------------------------- # 
274
    
275
    store = ModbusSlaveContext(
276
        di=ModbusSequentialDataBlock(32768, [0]*200),
277
        co=ModbusSequentialDataBlock(32768, [0]*200),
278
        hr=ModbusSequentialDataBlock(32768, [0]*200),
279
        ir=ModbusSequentialDataBlock(32768, [0]*200),zero_mode=True)
280
    context = ModbusServerContext(slaves=store, single=True)
281

    
282
    store.setValues(MB_DI, BIT_SAFETY_BTN, [1])
283
    store.setValues(MB_DI, BIT_BKEY, [1])
284
    # ----------------------------------------------------------------------- # 
285
    # initialize the server information
286
    # ----------------------------------------------------------------------- # 
287
    identity = ModbusDeviceIdentification()
288
    identity.VendorName = 'pymodbus'
289
    identity.ProductCode = 'PM'
290
    identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
291
    identity.ProductName = 'pymodbus Server'
292
    identity.ModelName = 'pymodbus Server'
293
    identity.MajorMinorRevision = '1.0'
294

    
295
    # ----------------------------------------------------------------------- # 
296
    # run the server you want
297
    # ----------------------------------------------------------------------- # 
298
    time = 0.333  # 333 mseconds delay
299
    loop = LoopingCall(f=updating_writer, a=(context,))
300
    loop.start(time, now=False) # initially delay by time
301
    StartTcpServer(context, identity=identity, address=("localhost", 1502))
302

    
303

    
304
bit_teach = 0
305
bit_rdy = [0]
306
bit_data_change = [0,0]
307
bit_motor = [0,0]
308
bit_play = [0,0]
309
learned_curve = []
310
index_curve = 0
311
cycles_no = 0
312
array_pos = 0
313
quality = [0,0,0]
314
# array with measurement values created #
315
meas_array = [(j) for j in range(270)]
316

    
317
if __name__ == "__main__":
318
    run_updating_server()
(3-3/3)