1
2
3
4
5
6
7
8 import Automata
9
10 TAB='\t'
11
13 """A Class to create a Mealy machine Controller from a DFA Controller.
14 The method L{CMealyMachine.getPLCCode} exploits the Mealy machine in order to produce the PLC control program."""
15
17 """
18 Creates a Mealy machine Controller from a DFA Controller.
19
20 This constructor builds automatically the Mealy machine.
21
22 @type controller: a L{Automata.CAutomaton} instance
23 @param controller: The DFA Controller which has to be converted into a Mealy machine Controller
24 @return: void
25 """
26
27 self.__controller=controller
28 self.__sequences={}
29
30
31
32 states=set([controller.getInitialStates()[0]])
33 done=set()
34
35 while (len(states)):
36 newstates=set()
37
38 for s in states:
39 stateseq=[]
40 self.__sequences[s.name]=stateseq
41
42 for t in s.getTransitions():
43 if (not controller.getEvent(t).isControllable()):
44 mealyset=[t]
45 s.getTransitions()[t].getMealyList(mealyset)
46
47 stateseq.append(mealyset)
48
49 for x in mealyset:
50 if isinstance(x,Automata.CAutomaton._CAutomaton__CState):
51 if x.name not in self.__sequences:
52 newstates.add(x)
53 states=newstates
54
56 return s.lstrip('q')
57
59 if i.find('_1')!=-1:
60 return i.rstrip('_1')
61 elif i.find('_0')!=-1:
62 return 'NOT '+i.rstrip('_0')
63 return i
64
66 if o.find('_1')!=-1:
67 a='SET '+ o.rstrip('_1')+';\n'
68 return a
69 elif o.find('_0')!=-1:
70 a='RESET '+o.rstrip('_0')+';\n'
71 return a
72 return o
73
75 """
76 Returns the Mealy machine represented as an Automaton.
77
78 @return: a L{Automata.CAutomaton} instance
79 """
80 ma=Automata.CAutomaton('Mealy Machine','0','A Mealy Machine representing a deterministic controller')
81 ids=0
82 ide=0
83 for state,seq in self.__sequences.iteritems():
84 newstate=ma.addState(str(ids),state,'',state=='q0',False)
85 for s in seq:
86 s.reverse()
87 ce=s.pop()
88 eventchain=''
89 parenthesis=True
90 while not isinstance(ce,Automata.CAutomaton._CAutomaton__CState):
91 eventchain=eventchain+ce+','
92 if parenthesis:
93 eventchain=eventchain+'{'
94 parenthesis=False
95 ce=s.pop()
96 eventchain=eventchain.rstrip(',')
97 eventchain=eventchain+'}'
98
99 ma.addEvent(str(ide),eventchain,'',True)
100 newstate._CState__transitions[eventchain]=ce.name
101 ide+=1
102 ids+=1
103
104 for state in ma.getStates():
105 for t in state.getTransitions():
106 state._CState__transitions[t]=ma.getState(state._CState__transitions[t])
107 return ma
108
109
111 """
112 Write the PLC control program in ST language to the specified filename.
113
114 The Mealy machine is processed in order to produce the code.
115
116 @type filename: string
117 @param filename: the output file path where to write the code
118 @return: void
119 """
120
121 EXTIF='IF (STATE='
122
123 f=open(filename, 'w')
124 f.write('PROGRAM\n\n')
125 outevents=set()
126 for state,seq in self.__sequences.iteritems():
127 f.write('(*PHRASE*)\n')
128 f.write(EXTIF+self.__processState(state)+') THEN\n')
129 INTIF='IF ('
130 for s in seq:
131 s.reverse()
132 f.write(TAB+INTIF+self.__processInput(s.pop())+') THEN\n')
133 INTIF='ELSIF ('
134 ce=s.pop()
135 while not isinstance(ce,Automata.CAutomaton._CAutomaton__CState):
136 outevents.add(ce.rstrip('_10'))
137 f.write(TAB+TAB+self.__processOutput(ce))
138 ce=s.pop()
139 f.write(TAB+TAB+'NEXTSTATE:='+self.__processState(ce.getName())+';\n')
140 f.write(TAB+'END_IF;\n')
141 f.write('END_IF;\n')
142 f.write('(*END_PHRASE*)\n\n')
143 f.write('(*PHRASE*)\n')
144 f.write('STATE:=NEXTSTATE;\n')
145 f.write('(*END_PHRASE*)\n\n')
146 f.write('(*PHRASE*)\n')
147 f.write('IF ( S1pb_emergency OR S2pb_emergency OR S3pb_emergency OR S4pb_emergency ) THEN\n')
148 f.write(TAB+'STATE:=0;\n')
149 for oe in outevents:
150 f.write(TAB+'RESET '+oe+';\n')
151 f.write('END_IF;\n')
152 f.write('(*END_PHRASE*)\n')
153 f.write('\nEND_PROGRAM\n')
154 f.write('[EOF]')
155 f.close()
156