-
Notifications
You must be signed in to change notification settings - Fork 0
/
state.py
executable file
·163 lines (147 loc) · 6.48 KB
/
state.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import time
import traceback
import datafiles
from TimeTrigger import TimeTrigger
class State(object):
knownStates = { }
ACTION_BEGIN = 1
ACTION_RESUME = 2
ACTION_END = 3
current = None
start = 0
empty = False
greasy = False
delayed = None
dstart = 0
dempty = False
dgreasy = False
@staticmethod
def get(letter,empty,greasy=False):
return State.knownStates[letter][empty][greasy]
@staticmethod
def setCurrent(letter,empty,greasy=False):
State.current = State.get(letter,empty,greasy)
State.empty = empty
State.greasy = greasy
# print (State.current.letter)
return State.current
@staticmethod
def transitCurrent(step, action, now=int(time.time()) ):
(State.start,State.current, State.empty, State.greasy) = State.current.transit(State.empty, State.greasy, step, action, State.start, now=now)
# print (State.current.letter)
@staticmethod
def transitDelayed(step, action, now=int(time.time()) ):
(State.dstart,State.delayed, State.dempty, State.dgreasy) = State.current.transit(State.empty, State.greasy, step, action, State.start, toBeSaved=False, now=now)
# print (State.delayed.letter)
@staticmethod
def loadCurrent(): # returns timestamp and current state
try:
with open(datafiles.paramfile("state.csv")) as f:
stateData = f.read()
# print (stateData)
data = stateData.split('\n')
if data and len(data) >= 2:
data = data[1].split('\t')
if len(data) >= 2:
since = data[0]
stateLetter = data[1]
if len(data) >= 4:
State.empty = bool(data[2])
State.greasy = bool(data[3])
if stateLetter and stateLetter[0] and stateLetter in State.knownStates:
State.current = State.knownStates[stateLetter[0]][State.empty][State.greasy]
return int(since), State.current, State.empty, State.greasy
State.setCurrent('s',False,False)
State.saveCurrent()
except IOError: # unknown previous state
State.setCurrent('s',False,False)
State.saveCurrent()
return 0,State.current,False,False # If state unknown, it is dirty !
@staticmethod
def saveCurrent(now=int(time.time())):
try:
State.current.save(State.empty,State.greasy,State.start)
except IOError: # no place to save current state ?
traceback.print_exc()
@staticmethod
def popDelayed(now=int(time.time())):
if State.delayed:
State.start = now
State.empty = State.dempty
State.greasy = State.dgreasy
State.current = State.delayed
TimeTrigger.resets()
State.saveCurrent()
State.delayed = None
def __init__(self, letter, labels, color, transitions, emptiness=None, greasiness=None):
#cohorts.catalog[address] = self Done by the threading class...
if emptiness is None:
emptiness = [False, True]
if greasiness is None:
greasiness = [False, True]
self.letter = letter
self.color = color
self.labels = labels
self.transitions = transitions
if letter not in State.knownStates:
State.knownStates[letter] = [[None,None],[None,None]]
for empty in emptiness:
for greasy in greasiness:
State.knownStates[letter][empty][greasy] = self
def transit(self,empty,greasy,step,action, start, toBeSaved=True, now=int(time.time()) ):
for (actDone,nextState) in self.transitions:
if actDone == action:
if nextState is None:
newState = State.get(self.letter,empty,greasy)
elif isinstance(nextState, list):
newLetter = None
if len(nextState):
if step == State.ACTION_BEGIN:
newLetter = nextState[0]
elif step == State.ACTION_RESUME:
newLetter = nextState[0 if (len(nextState) <= 1) else 1]
else: # ACTION_END
newLetter = nextState[len(nextState) - 1]
if isinstance(newLetter, list):
if newLetter[1] is not None:
empty = newLetter[1]
if newLetter[2] is not None:
greasy = newLetter[2]
newLetter = newLetter[0]
if not newLetter:
newLetter = self.letter
newState = State.get(newLetter,empty,greasy)
elif nextState:
newState = State.get(nextState,empty,greasy)
else: # empty = same state
newState = State.get(self.letter,empty,greasy)
if newState.letter != self.letter:
if toBeSaved:
TimeTrigger.resets()
newState.save(empty, greasy, now)
return now, newState,empty, greasy
else:
return start, newState,empty,greasy
print ("Unknown action=%s for state=%s" % (action,self.letter))
try:
return State.get('?',empty,greasy).transit(empty,greasy,step,action, start, toBeSaved=toBeSaved, now=now )
except:
print ("IMPOSSIBLE action=%s for state=%s" % (action,self.letter))
return start,self,empty,greasy
def allowedActions (self):
result = ""
for (actDone,nextState) in self.transitions:
result += actDone
if 'O' in result:
result += 'N' # Cleaning parameters and Pasteurisation parameters are both allowed most of the time.
return result
def save(self, empty, greasy=False, now=int(time.time()) ):
try:
with open(datafiles.paramfile("state.csv"), "w") as data_file:
data_file.write("epoch_sec\tstate\tempty\tgreasy\n")
data_file.write("%d\t%s\t%d\t%d\n"%(now, self.letter, empty, greasy))
# print ("%d\t%s\t%d\t%d\n"%(now, self.letter, empty, greasy))
except IOError: # unknown previous state
traceback.print_exc()