Passed
Pull Request — master (#348)
by
unknown
04:15
created

asyncua.common.statemachine   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 606
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 362
dl 0
loc 606
rs 5.04
c 0
b 0
f 0
wmc 57

34 Methods

Rating   Name   Duplication   Size   Complexity  
A FiniteStateMachineTypeClass.__init__() 0 7 2
A ProgramStateMachineTypeClass.install() 0 10 1
A StateMachineTypeClass.write_state() 0 4 1
A StateMachineTypeClass.init() 0 10 2
A ProgramStateMachineTypeClass.Resume() 0 5 2
A FiniteStateMachineTypeClass.set_avalible_states() 0 3 1
A StateMachineTypeClass.add_transition() 0 7 1
A ProgramStateMachineTypeClass.SuspendedToRunning() 0 21 1
A ShelvedStateMachineTypeClass.__init__() 0 6 2
A FiniteStateMachineTypeClass.find_all_states() 0 2 1
A FiniteStateMachineTypeClass.init() 0 6 1
A ProgramStateMachineTypeClass.SuspendedToHalted() 0 21 1
A ProgramStateMachineTypeClass.ReadyToRunning() 0 21 1
B StateMachineTypeClass.__init__() 0 23 5
A StateMachineTypeClass.change_state() 0 17 4
A ExclusiveLimitStateMachineTypeClass.__init__() 0 6 2
A ProgramStateMachineTypeClass.RunningToHalted() 0 21 1
A ProgramStateMachineTypeClass.HaltedToReady() 0 21 1
B ProgramStateMachineTypeClass.__init__() 0 61 2
A ProgramStateMachineTypeClass.SuspendedToReady() 0 21 1
A ProgramStateMachineTypeClass.Start() 0 5 2
A StateMachineTypeClass.install() 0 12 1
A ProgramStateMachineTypeClass.Reset() 0 5 2
A ProgramStateMachineTypeClass.Suspend() 0 5 2
A StateMachineTypeClass.add_state() 0 12 1
A ProgramStateMachineTypeClass.ReadyToHalted() 0 21 1
A StateMachineTypeClass.write_transition() 0 4 1
A ProgramStateMachineTypeClass.RunningToReady() 0 21 1
A FiniteStateMachineTypeClass.set_avalible_transitions() 0 3 1
A FiniteStateMachineTypeClass.find_all_transitions() 0 2 1
A ProgramStateMachineTypeClass.RunningToSuspended() 0 21 1
A ProgramStateMachineTypeClass.Halt() 0 9 4
A FileTransferStateMachineTypeClass.__init__() 0 6 2
A FiniteStateMachineTypeClass.install() 0 10 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A main() 0 47 3

How to fix   Complexity   

Complexity

Complex classes like asyncua.common.statemachine often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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