Passed
Pull Request — master (#348)
by
unknown
02:24
created

ProgramStateMachineTypeClass.Suspend()   A

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
'''
2
https://reference.opcfoundation.org/v104/Core/docs/Part10/
3
https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.1/
4
Basic statemachines described in OPC UA Spec.:
5
StateMachineType
6
FiniteStateMachineType
7
ExclusiveLimitStateMachineType
8
FileTransferStateMachineType
9
ProgramStateMachineType
10
ShelvedStateMachineType
11
Relevant information:
12
Overview - https://reference.opcfoundation.org/v104/Core/docs/Part10/5.2.3/#5.2.3.1
13
States - https://reference.opcfoundation.org/v104/Core/docs/Part10/5.2.3/#5.2.3.2
14
Transitions - https://reference.opcfoundation.org/v104/Core/docs/Part10/5.2.3/#5.2.3.3
15
Events - https://reference.opcfoundation.org/v104/Core/docs/Part10/5.2.5/
16
'''
17
import asyncio, logging, datetime
18
19
#FIXME 
20
# -change to relativ imports!
21
# -remove unused imports
22
from asyncua import Server, ua, Node
23
from asyncua.common.event_objects import TransitionEvent, ProgramTransitionEvent
24
25
_logger = logging.getLogger(__name__)
26
27
class StateMachineTypeClass(object):
28
    '''
29
    Implementation of an StateMachineType (most basic type)
30
    CurrentState: Mandatory
31
    LastTransition: Optional
32
    Generates TransitionEvent's
33
    '''
34
    def __init__(self, server=None, parent=None, idx=None, name=None):
35
        if not isinstance(server, Server): 
36
            raise ValueError
37
        if not isinstance(parent, Node): 
38
            raise ValueError
39
        if idx == None:
40
            idx = parent.nodeid.NamespaceIndex
41
        if name == None:
42
            name = "StateMachine"
43
        self.locale = "en-US"
44
        self._server = server
45
        self._parent = parent
46
        self._state_machine_node = None
47
        self._state_machine_type = ua.NodeId(2299, 0) #StateMachineType
48
        self._name = name
49
        self._idx = idx
50
        self._optionals = False
51
        self._current_state_node = None
52
        self._current_state_id_node = None
53
        self._last_transition_node = None
54
        self._last_transition_id_node = None
55
        self._evgen = None
56
        self.evtype = TransitionEvent()
57
58
    class State(object):
59
        '''
60
        Helperclass for States
61
        https://reference.opcfoundation.org/v104/Core/docs/Part5/B.4.3/
62
        '''
63
        def __init__(self, name, id=0, node=None):
64
            self.name = name
65
            self.id = str(id)
66
            self.number = id
67
            self.node = node #will be written from statemachine.add_state() or you need to overwrite it if the state is part of xml
68
69
    class Transition(object):
70
        '''
71
        Helperclass for Transitions
72
        https://reference.opcfoundation.org/v104/Core/docs/Part5/B.4.4/
73
        '''
74
        def __init__(self, name, id=0, node=None):
75
            self.name = name
76
            self.id = str(id)
77
            self.number = id
78
            self._transitiontime = datetime.datetime.utcnow() #will be overwritten from _write_transition()
79
            self._effectivetransitiontime = datetime.datetime.utcnow() #will be overwritten from _write_transition()
80
            self.node = node #will be written from statemachine.add_state() or you need to overwrite it if the state is part of xml
81
82
    async def install(self, optionals=False):
83
        '''
84
        setup adressspace
85
        '''
86
        self._optionals = optionals
87
        self._state_machine_node = await self._parent.add_object(
88
            self._idx, 
89
            self._name, 
90
            objecttype=self._state_machine_type, 
91
            instantiate_optional=optionals
92
            )
93
        await self.init(self._state_machine_node)
94
    
95
    async def init(self, statemachine):
96
        '''
97
        initialize and get subnodes
98
        '''
99
        #FIXME try to get children of statemachine with typdefinition initstate if no child -> no states (possible if the statemachine is not part of xml)
100
        self._current_state_node = await statemachine.get_child(["CurrentState"])
101
        self._current_state_id_node = await statemachine.get_child(["CurrentState","Id"])
102
        if self._optionals:
103
            self._last_transition_node = await statemachine.get_child(["LastTransition"])
104
            self._last_transition_id_node = await statemachine.get_child(["LastTransition","Id"])
105
        self._evgen = await self._server.get_event_generator(self.evtype, self._state_machine_node)
106
107
    async def change_state(
108
        self, 
109
        state, 
110
        transition=None, 
111
        event_msg=None,
112
        severity=500
113
        ):
114
        '''
115
        method to change the state of the statemachine
116
        state (type StateTypeClass mandatory)
117
        transition (type TransitionTypeClass optional)
118
        event_msg (type string optional)
119
        severity (type Int optional)
120
        '''
121
        #FIXME check StateType exist
122
        #FIXME check TransitionTypeType exist
123
        await self._write_state(state)
124
        if transition:
125
            await self._write_transition(transition)
126
        if event_msg:
127
            if isinstance(event_msg, (type(""))):
128
                event_msg = ua.LocalizedText(event_msg, self.locale)
129
            self._evgen.event.Message = event_msg
130
            self._evgen.event.Severity = severity
131
            await self._evgen.trigger()
132
133
    async def _write_state(self, state):
134
        await self._current_state_node.write_value(ua.LocalizedText(state.name, self.locale))
135
        if state.node:
136
            await self._current_state_id_node.write_value(state.node.nodeid)
137
138
    async def _write_transition(self, transition):
139
        await self._last_transition_node.write_value(ua.LocalizedText(transition.name, self.locale))
140
        if transition.node:
141
            await self._last_transition_id_node.write_value(transition.node.nodeid)
142
        transition._transitiontime = datetime.datetime.utcnow()
143
        transition._effectivetransitiontime = datetime.datetime.utcnow()
144
    
145
    async def add_state(self, state, state_type=ua.NodeId(2307, 0), optionals=False):
146
        '''
147
        state: StateTypeClass
148
        InitialStateType: ua.NodeId(2309, 0)
149
        StateType: ua.NodeId(2307, 0)
150
        ChoiceStateType: ua.NodeId(15109,0)
151
        '''
152
        if not isinstance(state, self.State):
153
            raise ValueError
154
        state.node = await self._state_machine_node.add_object(
155
            self._idx, 
156
            state.name, 
157
            objecttype=state_type, 
158
            instantiate_optional=optionals
159
            )
160
        state_number = await state.node.get_child(["StateNumber"])
161
        await state_number.write_value(state.number, ua.VariantType.UInt32)
162
        return state.node
163
164
    async def add_transition(self, transition, transition_type=ua.NodeId(2310, 0), optionals=False):
165
        '''
166
        transition: TransitionTypeClass
167
        transition_type: ua.NodeId(2310, 0)
168
        '''
169
        if not isinstance(transition, self.Transition):
170
            raise ValueError
171
        transition.node = await self._state_machine_node.add_object(
172
            self._idx, 
173
            transition.name, 
174
            objecttype=transition_type, 
175
            instantiate_optional=optionals
176
            )
177
        transition_number = await transition.node.get_child(["TransitionNumber"])
178
        await transition_number.write_value(transition.number, ua.VariantType.UInt32)
179
        return transition.node
180
181
    async def remove(self, nodes):
182
        #FIXME
183
        raise NotImplementedError
184
185
class FiniteStateMachineTypeClass(StateMachineTypeClass):
186
    '''
187
    Implementation of an FiniteStateMachineType a little more advanced than the basic one
188
    if you need to know the avalible states and transition from clientside
189
    '''
190
    def __init__(self, server=None, parent=None, idx=None, name=None):
191
        super().__init__(server, parent, idx, name)
192
        if name == None:
193
            name = "FiniteStateMachine"
194
        self._state_machine_type = ua.NodeId(2771, 0)
195
        self._avalible_states_node = None
196
        self._avalible_transitions_node = None
197
198
    async def install(self, optionals=False):
199
        '''
200
        setup adressspace and initialize 
201
        '''
202
        self._optionals = optionals
203
        self._state_machine_node = await self._parent.add_object(
204
            self._idx, 
205
            self._name, 
206
            objecttype=self._state_machine_type, 
207
            instantiate_optional=optionals
208
            )
209
210
    async def init(self, avalible_states, avalible_transitions, ):
211
        #FIXME get children and map children
212
        #await self.find_all_states()
213
        await self.set_avalible_states(avalible_states)
214
        #await self.find_all_transitions()
215
        await self.set_avalible_transitions(avalible_transitions)
216
217
    async def set_avalible_states(self, states):
218
        #check if its list
219
        await self._avalible_states_node.write_value(states, varianttype=ua.VariantType.NodeId)
220
221
    async def set_avalible_transitions(self, transitions):
222
        #check if its list
223
        await self._avalible_transitions_node.write_value(transitions, varianttype=ua.VariantType.NodeId)
224
225
    async def find_all_states(self):
226
        return NotImplementedError
227
    
228
    async def find_all_transitions(self):
229
        return NotImplementedError
230
231
class ExclusiveLimitStateMachineTypeClass(FiniteStateMachineTypeClass):
232
    '''
233
    NOT IMPLEMENTED "ExclusiveLimitStateMachineType"
234
    '''
235
    def __init__(self, server=None, parent=None, idx=None, name=None):
236
        super().__init__(server, parent, idx, name)
237
        if name == None:
238
            name = "ExclusiveLimitStateMachine"
239
        self._state_machine_type = ua.NodeId(9318, 0)
240
        raise NotImplementedError
241
242
class FileTransferStateMachineTypeClass(FiniteStateMachineTypeClass):
243
    '''
244
    NOT IMPLEMENTED "FileTransferStateMachineType"
245
    '''
246
    def __init__(self, server=None, parent=None, idx=None, name=None):
247
        super().__init__(server, parent, idx, name)
248
        if name == None:
249
            name = "FileTransferStateMachine"
250
        self._state_machine_type = ua.NodeId(15803, 0)
251
        raise NotImplementedError
252
253
class ProgramStateMachineTypeClass(FiniteStateMachineTypeClass):
254
    '''
255
    https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.3/
256
    Implementation of an ProgramStateMachine its quite a complex statemachine with the 
257
    optional possibility to make the statchange from clientside via opcua-methods
258
    '''
259
    def __init__(self, server=None, parent=None, idx=None, name=None):
260
        super().__init__(server, parent, idx, name)
261
        if name == None:
262
            name = "ProgramStateMachine"
263
        self._state_machine_type = ua.NodeId(2391, 0)
264
        self.evtype = ProgramTransitionEvent()
265
266
        # 5.2.3.2 ProgramStateMachineType states
267
        self._ready_state_node = None #State node
268
        self._halted_state_node = None #State node
269
        self._running_state_node = None #State node
270
        self._suspended_state_node = None #State node
271
272
        # 5.2.3.3 ProgramStateMachineType transitions
273
        self._halted_to_ready_node = None #Transition node
274
        self._ready_to_running_node = None #Transition node
275
        self._running_to_halted_node = None #Transition node
276
        self._running_to_ready_node = None #Transition node
277
        self._running_to_suspended_node = None #Transition node
278
        self._suspended_to_running_node = None #Transition node
279
        self._suspended_to_halted_node = None #Transition node
280
        self._suspended_to_ready_node = None #Transition node
281
        self._ready_to_halted_node = None #Transition node
282
283
        # 5.2.3.2 ProgramStateMachineType states
284
        self._halted_state_id_node = None #State property (StateNumber value 11)
285
        self._ready_state_id_node = None #State property (StateNumber value 12)
286
        self._running_state_id_node = None #State property (StateNumber value 13)
287
        self._suspended_state_id_node = None #State property (StateNumber value 14)
288
289
        # 5.2.3.3 ProgramStateMachineType transitions
290
        self._halted_to_ready_id_node = None #Transition property (TransitionNumber value 1)
291
        self._ready_to_running_id_node = None #Transition property (TransitionNumber value 2)
292
        self._running_to_halted_id_node = None #Transition property (TransitionNumber value 3)
293
        self._running_to_ready_id_node = None #Transition property (TransitionNumber value 4)
294
        self._running_to_suspended_id_node = None #Transition property (TransitionNumber value 5)
295
        self._suspended_to_running_id_node = None #Transition property (TransitionNumber value 6)
296
        self._suspended_to_halted_id_node = None #Transition property (TransitionNumber value 7)
297
        self._suspended_to_ready_id_node = None #Transition property (TransitionNumber value 8)
298
        self._ready_to_halted_id_node = None #Transition property (TransitionNumber value 9)
299
300
        # 4.2.7 Program Control Methods (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.7/)
301
        self._halt_method_node = None #uamethod node
302
        self._reset_method_node = None #uamethod node
303
        self._resume_method_node = None #uamethod node
304
        self._start_method_node = None #uamethod node
305
        self._suspend_method_node = None #uamethod node
306
307
        #can be overwritten if you want a different language
308
        self.localizedtext_ready = ua.LocalizedText("Ready", "en-US")
309
        self.localizedtext_running = ua.LocalizedText("Running", "en-US")
310
        self.localizedtext_halted = ua.LocalizedText("Halted", "en-US")
311
        self.localizedtext_suspended= ua.LocalizedText("Suspended", "en-US")
312
        self.localizedtext_halted_to_ready = ua.LocalizedText("HaltedToReady", "en-US")
313
        self.localizedtext_ready_to_running = ua.LocalizedText("ReadyToRunning", "en-US")
314
        self.localizedtext_running_to_halted = ua.LocalizedText("RunningToHalted", "en-US")
315
        self.localizedtext_running_to_ready = ua.LocalizedText("RunningToReady", "en-US")
316
        self.localizedtext_running_to_suspended = ua.LocalizedText("RunningToSuspended", "en-US")
317
        self.localizedtext_suspended_to_running = ua.LocalizedText("SuspendedToRunning", "en-US")
318
        self.localizedtext_suspended_to_halted = ua.LocalizedText("SuspendedToHalted", "en-US")
319
        self.localizedtext_suspended_to_ready = ua.LocalizedText("SuspendedToReady", "en-US")
320
        self.localizedtext_ready_to_halted = ua.LocalizedText("ReadyToHalted", "en-US")
321
322
    async def install(self, optionals=False):
323
        '''
324
        setup adressspace and initialize 
325
        '''
326
        self._optionals = optionals
327
        self._state_machine_node = await self._parent.add_object(
328
            self._idx, 
329
            self._name, 
330
            objecttype=self._state_machine_type, 
331
            instantiate_optional=optionals
332
            )
333
        #FIXME get children and map children
334
335
    #Transition
336
    async def HaltedToReady(self):
337
        await self._current_state.write_value(
338
            self.localizedtext_ready,
339
            varianttype=ua.VariantType.LocalizedText
340
            ) 
341
        await self._current_state_id.write_value(
342
            self._ready_state.nodeid, 
343
            varianttype=ua.VariantType.NodeId
344
            )
345
        await self._last_transition.write_value(
346
            self.localizedtext_halted_to_ready,
347
            varianttype=ua.VariantType.LocalizedText
348
            ) 
349
        await self._last_transition_id.write_value(
350
            self._halted_to_ready.nodeid,
351
            varianttype=ua.VariantType.NodeId
352
            )
353
        #FIXME 
354
        # trigger ProgramTransitionEventType and 
355
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
356
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
357
358
    #Transition
359
    async def ReadyToRunning(self):
360
        await self._current_state.write_value(
361
            self.localizedtext_running,
362
            varianttype=ua.VariantType.LocalizedText
363
            ) 
364
        await self._current_state_id.write_value(
365
            self._running_state.nodeid, 
366
            varianttype=ua.VariantType.NodeId
367
            )
368
        await self._last_transition.write_value(
369
            self.localizedtext_ready_to_running,
370
            varianttype=ua.VariantType.LocalizedText
371
            ) 
372
        await self._last_transition_id.write_value(
373
            self._ready_to_running.nodeid, 
374
            varianttype=ua.VariantType.NodeId
375
            )
376
        #FIXME 
377
        # trigger ProgramTransitionEventType and 
378
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
379
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
380
381
    #Transition
382
    async def RunningToHalted(self):
383
        await self._current_state.write_value(
384
            self.localizedtext_halted,
385
            varianttype=ua.VariantType.LocalizedText
386
            ) 
387
        await self._current_state_id.write_value(
388
            self._halted_state.nodeid, 
389
            varianttype=ua.VariantType.NodeId
390
            )
391
        await self._last_transition.write_value(
392
            self.localizedtext_running_to_halted,
393
            varianttype=ua.VariantType.LocalizedText
394
            ) 
395
        await self._last_transition_id.write_value(
396
            self._running_to_halted.nodeid, 
397
            varianttype=ua.VariantType.NodeId
398
            )
399
        #FIXME 
400
        # trigger ProgramTransitionEventType and 
401
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
402
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
403
404
    #Transition
405
    async def RunningToReady(self):
406
        await self._current_state.write_value(
407
            self.localizedtext_ready,
408
            varianttype=ua.VariantType.LocalizedText
409
            ) 
410
        await self._current_state_id.write_value(
411
            self._ready_state.nodeid, 
412
            varianttype=ua.VariantType.NodeId
413
            )
414
        await self._last_transition.write_value(
415
            self.localizedtext_running_to_ready,
416
            varianttype=ua.VariantType.LocalizedText
417
            ) 
418
        await self._last_transition_id.write_value(
419
            self._running_to_ready.nodeid, 
420
            varianttype=ua.VariantType.NodeId
421
            )
422
        #FIXME 
423
        # trigger ProgramTransitionEventType and 
424
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
425
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
426
427
    #Transition
428
    async def RunningToSuspended(self):
429
        await self._current_state.write_value(
430
            self.localizedtext_suspended,
431
            varianttype=ua.VariantType.LocalizedText
432
            ) 
433
        await self._current_state_id.write_value(
434
            self._suspended_state.nodeid, 
435
            varianttype=ua.VariantType.NodeId
436
            )
437
        await self._last_transition.write_value(
438
            self.localizedtext_running_to_suspended,
439
            varianttype=ua.VariantType.LocalizedText
440
            ) 
441
        await self._last_transition_id.write_value(
442
            self._running_to_suspended.nodeid, 
443
            varianttype=ua.VariantType.NodeId
444
            )
445
        #FIXME 
446
        # trigger ProgramTransitionEventType and 
447
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
448
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
449
450
    #Transition 
451
    async def SuspendedToRunning(self):
452
        await self._current_state.write_value(
453
            self.localizedtext_running,
454
            varianttype=ua.VariantType.LocalizedText
455
            ) 
456
        await self._current_state_id.write_value(
457
            self._running_state.nodeid, 
458
            varianttype=ua.VariantType.NodeId
459
            )
460
        await self._last_transition.write_value(
461
            self.localizedtext_suspended_to_running,
462
            varianttype=ua.VariantType.LocalizedText
463
            )
464
        await self._last_transition_id.write_value(
465
            self._suspended_to_running.nodeid, 
466
            varianttype=ua.VariantType.NodeId
467
            )
468
        #FIXME 
469
        # trigger ProgramTransitionEventType and 
470
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
471
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
472
473
    #Transition
474
    async def SuspendedToHalted(self):
475
        await self._current_state.write_value(
476
            self.localizedtext_halted,
477
            varianttype=ua.VariantType.LocalizedText
478
            ) 
479
        await self._current_state_id.write_value(
480
            self._halted_state.nodeid, 
481
            varianttype=ua.VariantType.NodeId
482
            )
483
        await self._last_transition.write_value(
484
            self.localizedtext_suspended_to_halted,
485
            varianttype=ua.VariantType.LocalizedText
486
            ) 
487
        await self._last_transition_id.write_value(
488
            self._suspended_to_halted.nodeid, 
489
            varianttype=ua.VariantType.NodeId
490
            )
491
        #FIXME 
492
        # trigger ProgramTransitionEventType and 
493
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
494
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
495
496
    #Transition
497
    async def SuspendedToReady(self):
498
        await self._current_state.write_value(
499
            self.localizedtext_ready,
500
            varianttype=ua.VariantType.LocalizedText
501
            ) 
502
        await self._current_state_id.write_value(
503
            self._ready_state.nodeid, 
504
            varianttype=ua.VariantType.NodeId
505
            )
506
        await self._last_transition.write_value(
507
            self.localizedtext_suspended_to_ready,
508
            varianttype=ua.VariantType.LocalizedText
509
            ) 
510
        await self._last_transition_id.write_value(
511
            self._suspended_to_ready.nodeid, 
512
            varianttype=ua.VariantType.NodeId
513
            )
514
        #FIXME 
515
        # trigger ProgramTransitionEventType and 
516
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
517
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
518
519
    #Transition 
520
    async def ReadyToHalted(self):
521
        await self._current_state.write_value(
522
            self.localizedtext_halted,
523
            varianttype=ua.VariantType.LocalizedText
524
            ) 
525
        await self._current_state_id.write_value(
526
            self._halted_state.nodeid, 
527
            varianttype=ua.VariantType.NodeId
528
            )
529
        await self._last_transition.write_value(
530
            self.localizedtext_ready_to_halted,
531
            varianttype=ua.VariantType.LocalizedText
532
            ) 
533
        await self._last_transition_id.write_value(
534
            self._ready_to_halted.nodeid, 
535
            varianttype=ua.VariantType.NodeId
536
            )
537
        #FIXME 
538
        # trigger ProgramTransitionEventType and 
539
        # AuditUpdateMethodEvents/AuditProgramTransitionEventType (https://reference.opcfoundation.org/v104/Core/docs/Part10/4.2.2/)
540
        return ua.StatusCode(ua.status_codes.StatusCodes.Good)
541
542
    #method to be linked to uamethod
543
    async def Start(self):
544
        if await self._current_state.read_value() == self.localizedtext_ready:
545
            return await ReadyToRunning()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ReadyToRunning does not seem to be defined.
Loading history...
546
        else:
547
            return ua.StatusCode(ua.status_codes.StatusCodes.BadNotExecutable)
548
549
    #method to be linked to uamethod
550
    async def Suspend(self):
551
        if await self._current_state.read_value() == self.localizedtext_running:
552
            return await RunningToSuspended()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable RunningToSuspended does not seem to be defined.
Loading history...
553
        else:
554
            return ua.StatusCode(ua.status_codes.StatusCodes.BadNotExecutable)
555
556
    #method to be linked to uamethod
557
    async def Resume(self):
558
        if await self._current_state.read_value() == self.localizedtext_suspended:
559
            return await SuspendedToRunning()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable SuspendedToRunning does not seem to be defined.
Loading history...
560
        else:
561
            return ua.StatusCode(ua.status_codes.StatusCodes.BadNotExecutable)
562
563
    #method to be linked to uamethod
564
    async def Halt(self):
565
        if await self._current_state.read_value() == self.localizedtext_ready:
566
            return await ReadyToHalted()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ReadyToHalted does not seem to be defined.
Loading history...
567
        elif await self._current_state.read_value() == self.localizedtext_running:
568
            return await RunningToHalted()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable RunningToHalted does not seem to be defined.
Loading history...
569
        elif await self._current_state.read_value() == self.localizedtext_suspended:
570
            return await SuspendedToHalted()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable SuspendedToHalted does not seem to be defined.
Loading history...
571
        else:
572
            return ua.StatusCode(ua.status_codes.StatusCodes.BadNotExecutable)
573
574
    #method to be linked to uamethod
575
    async def Reset(self):
576
        if await self._current_state.read_value() == self.localizedtext_halted:
577
            return await HaltedToReady()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable HaltedToReady does not seem to be defined.
Loading history...
578
        else:
579
            return ua.StatusCode(ua.status_codes.StatusCodes.BadNotExecutable)
580
581
class ShelvedStateMachineTypeClass(FiniteStateMachineTypeClass):
582
    '''
583
    NOT IMPLEMENTED "ShelvedStateMachineType"
584
    '''
585
    def __init__(self, server=None, parent=None, idx=None, name=None):
586
        super().__init__(server, parent, idx, name)
587
        if name == None:
588
            name = "ShelvedStateMachine"
589
        self._state_machine_type = ua.NodeId(2929, 0)
590
        raise NotImplementedError
591
592
593
594
#FIXME REMOVE BEFOR MERGE
595
#Devtest / Workbench
596
if __name__ == "__main__":
597
    async def main():
598
        logging.basicConfig(level=logging.INFO)
599
        _logger = logging.getLogger('asyncua')
600
601
        server = Server()
602
        await server.init()
603
604
        idx = await server.register_namespace("http://testnamespace.org/UA")
605
606
        mystatemachine = StateMachineTypeClass(server, server.nodes.objects, idx, "StateMachine")
607
        await mystatemachine.install(optionals=True)
608
609
        state1 = mystatemachine.State("Idle", 1)
610
        await mystatemachine.add_state(state1)
611
        state2 = mystatemachine.State("Loading", 2)
612
        await mystatemachine.add_state(state2)
613
        state3 = mystatemachine.State("Initializing", 3)
614
        await mystatemachine.add_state(state3)
615
        state4 = mystatemachine.State("Processing", 4)
616
        await mystatemachine.add_state(state4)
617
        state5 = mystatemachine.State("Finished", 5)
618
        await mystatemachine.add_state(state5)
619
620
        trans1 = mystatemachine.Transition("to Idle", 1)
621
        await mystatemachine.add_transition(trans1)
622
        trans2 = mystatemachine.Transition("to Loading", 2)
623
        await mystatemachine.add_transition(trans2)
624
        trans3 = mystatemachine.Transition("to Initializing", 3)
625
        await mystatemachine.add_transition(trans3)
626
        trans4 = mystatemachine.Transition("to Processing", 4)
627
        await mystatemachine.add_transition(trans4)
628
        trans5 = mystatemachine.Transition("to Finished", 5)
629
        await mystatemachine.add_transition(trans5)
630
631
        await mystatemachine.change_state(state1, trans1, f"{mystatemachine._name}: Idle", 300)
632
633
        mystatemachine2 = StateMachineTypeClass(server, server.nodes.objects, idx, "StateMachine2")
634
        await mystatemachine2.install(optionals=True)
635
636
        sm2state1 = mystatemachine2.State("Idle", 1)
637
        await mystatemachine2.add_state(sm2state1)
638
639
        async with server:
640
            while 1:
641
                await asyncio.sleep(2)
642
                await mystatemachine.change_state(state2, trans2, f"{mystatemachine._name}: Loading", 350)
643
                await asyncio.sleep(2)
644
                await mystatemachine.change_state(state3, trans3, f"{mystatemachine._name}: Initializing", 400)
645
                await asyncio.sleep(2)
646
                await mystatemachine.change_state(state4, trans4, f"{mystatemachine._name}: Processing", 600)
647
                await asyncio.sleep(2)
648
                await mystatemachine.change_state(state5, trans5, f"{mystatemachine._name}: Finished", 800)
649
                await asyncio.sleep(2)
650
                await mystatemachine.change_state(state1, trans1, f"{mystatemachine._name}: Idle", 500)
651
652
    asyncio.run(main())
653