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

StateMachineTypeClass.init()   A

Complexity

Conditions 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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