main.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. import matplotlib
  2. matplotlib.use("TkAgg")
  3. from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
  4. from matplotlib.figure import Figure
  5. from Tkinter import *
  6. import tkSimpleDialog
  7. import urllib
  8. import urllib2
  9. import json
  10. import time
  11. JUMP = 40
  12. MAX_WIDTH = 20 * JUMP
  13. MAX_HEIGHT = 20 * JUMP
  14. address = "http://127.0.0.1:8001"
  15. username = "test"
  16. root = Tk()
  17. canvas = Canvas(root, width=MAX_WIDTH, height=MAX_HEIGHT, bg="white")
  18. canvas.pack()
  19. name = 0
  20. class FakeLayer():
  21. def __init__(self, address):
  22. self.types = {}
  23. self.sources = {}
  24. self.targets = {}
  25. self.attrs = {}
  26. def read_available_attributes(self, name):
  27. if self.types[name] == "const":
  28. return ["value"]
  29. else:
  30. return []
  31. def read_attribute(self, name, attr):
  32. return self.attr.get(name, {}).get(attr, None)
  33. def set_attribute(self, name, attr, value):
  34. self.attrs[name][attr] = value
  35. def instantiate_block(self, name, block_type):
  36. self.types[name] = block_type
  37. def instantiate_link(self, name, link_type, source, target):
  38. self.types[name] = link_type
  39. self.sources[name] = source
  40. self.targets[name] = target
  41. self.attrs[name] = {}
  42. def simulate(self):
  43. pass
  44. def step(self):
  45. pass
  46. def pause(self):
  47. pass
  48. attribute = []
  49. available_attrs = []
  50. simulation = []
  51. #simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
  52. def poll(address):
  53. working_available_attrs = []
  54. working_simulation = None
  55. while 1:
  56. returnvalue = json.loads(urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read())
  57. print("Process " + str(returnvalue))
  58. if (returnvalue.startswith("AVAILABLE_ATTR_VALUE")):
  59. working_available_attrs.append([json.loads(returnvalue.split(" ", 1)[1]), None])
  60. elif (returnvalue.startswith("AVAILABLE_ATTR_TYPE")):
  61. working_available_attrs[-1][1] = json.loads(returnvalue.split(" ", 1)[1])
  62. elif (returnvalue.startswith("AVAILABLE_ATTR_END")):
  63. available_attrs.append(working_available_attrs)
  64. working_available_attrs = []
  65. elif (returnvalue.startswith("ATTR_VALUE")):
  66. v = returnvalue.split(" ", 1)[1]
  67. if v == "None":
  68. v = None
  69. else:
  70. v = json.loads(v)
  71. attribute.append(v)
  72. elif (returnvalue.startswith("SIM_TIME")):
  73. working_simulation = (json.loads(returnvalue.split(" ", 1)[1]), {})
  74. elif (returnvalue.startswith("SIM_PROBE")):
  75. blockname, blockvalue = returnvalue.split(" ", 1)[1].rsplit(" ", 1)
  76. working_simulation[1][json.loads(blockname)] = json.loads(blockvalue)
  77. elif (returnvalue.startswith("SIM_END")):
  78. simulation.append(working_simulation)
  79. working_simulation = None
  80. else:
  81. print("Error: got unknown result: " + returnvalue)
  82. class MvLayer():
  83. def __init__(self, address):
  84. import threading
  85. self.address = address
  86. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % username, "username": "user_manager"}))).read()
  87. thrd = threading.Thread(target=poll, args=[address])
  88. thrd.daemon = True
  89. thrd.start()
  90. def read_available_attributes(self, name):
  91. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"read_available_attributes"', "username": username}))).read()
  92. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": username}))).read()
  93. while not available_attrs:
  94. time.sleep(0.1)
  95. return available_attrs.pop(0)
  96. def read_attribute(self, name, attr):
  97. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"read_attribute"', "username": username}))).read()
  98. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": username}))).read()
  99. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % attr, "username": username}))).read()
  100. while not attribute:
  101. time.sleep(0.1)
  102. return attribute.pop(0)
  103. def set_attribute(self, name, attr, value):
  104. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"set_attribute"', "username": username}))).read()
  105. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % name, "username": username}))).read()
  106. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % attr, "username": username}))).read()
  107. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": json.dumps(value), "username": username}))).read()
  108. def instantiate_block(self, name, block_type):
  109. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"instantiate_node"', "username": username}))).read()
  110. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (block_type), "username": username}))).read()
  111. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (name), "username": username}))).read()
  112. def instantiate_link(self, name, link_type, source, target):
  113. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"instantiate_association"', "username": username}))).read()
  114. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (link_type), "username": username}))).read()
  115. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (name), "username": username}))).read()
  116. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (source), "username": username}))).read()
  117. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"%s"' % (target), "username": username}))).read()
  118. def simulate(self):
  119. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"simulate"', "username": username}))).read()
  120. def step(self):
  121. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"step"', "username": username}))).read()
  122. def pause(self):
  123. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": '"pause"', "username": username}))).read()
  124. def lower(value):
  125. return value / JUMP * JUMP
  126. def upper(value):
  127. return (value / JUMP + 1) * JUMP
  128. def avg(a, b):
  129. return float(a + b) / 2
  130. class InterfaceCore():
  131. mode = ""
  132. drawn = set()
  133. refs = dict()
  134. mv = MvLayer(address)
  135. #mv = FakeLayer(address)
  136. def set_mode(self, mode):
  137. self.mode = mode
  138. def clicked(self, event):
  139. if self.mode not in ["AdditionBlock", "NegatorBlock", "ConstantBlock", "MultiplyBlock", "ConstantBlock", "InverseBlock", "DelayBlock"]:
  140. print("Cannot create something not guaranteed to be block type!")
  141. else:
  142. if self.find((event.x, event.y)):
  143. # Something already there, so don't add, but modify
  144. lname = self.find((event.x, event.y))
  145. attrs = self.mv.read_available_attributes(lname)
  146. print("Managing " + str(attrs))
  147. if not attrs:
  148. print("No attrs to manage!")
  149. for attr, t in attrs:
  150. print("Reading data from " + str(attr))
  151. old_value = self.mv.read_attribute(lname, attr)
  152. if old_value == "None":
  153. old_value = None
  154. new_value = tkSimpleDialog.askstring("Attribute modification", attr, initialvalue=old_value)
  155. if t == "Float":
  156. new_value = float(new_value)
  157. else:
  158. print("Got unknown type: " + str(t))
  159. self.mv.set_attribute(lname, attr, new_value)
  160. else:
  161. global name
  162. x = event.x
  163. y = event.y
  164. self.mv.instantiate_block(str(name), self.mode)
  165. r = canvas.create_rectangle(lower(x), lower(y), upper(x), upper(y), fill="white")
  166. t = canvas.create_text(avg(lower(x), upper(x)), avg(lower(y), upper(y)), text=self.mode, fill="black")
  167. b = (lower(x), lower(y), upper(x), upper(y), str(name))
  168. self.drawn.add(b)
  169. self.refs[str(name)] = [r, t]
  170. name += 1
  171. def find(self, location):
  172. x, y = location
  173. for e in self.drawn:
  174. if (e[0] <= x and
  175. e[1] <= y and
  176. e[2] >= x and
  177. e[3] >= y):
  178. return e[4]
  179. print("Found nothing at that location!")
  180. return []
  181. def draw(self, start, end):
  182. source = self.find(start)
  183. target = self.find(end)
  184. print("Connect from %s to %s" % (source, target))
  185. if source and target:
  186. if self.mode not in ["Link", "InitialCondition"]:
  187. print("Cannot create something not guaranteed to be link type!")
  188. else:
  189. global name
  190. self.mv.instantiate_link(str(name), self.mode, source, target)
  191. self.refs[str(name)] = [canvas.create_line(start[0], start[1], end[0], end[1], fill="black", arrow=LAST)]
  192. name += 1
  193. core = InterfaceCore()
  194. def clicked(event):
  195. core.clicked(event)
  196. def draw(event):
  197. global start_location
  198. start_location = (event.x, event.y)
  199. def release(event):
  200. core.draw(start_location, (event.x, event.y))
  201. def simulate():
  202. core.mv.simulate()
  203. def step():
  204. core.mv.step()
  205. def pause():
  206. core.mv.pause()
  207. def addition():
  208. core.set_mode("AdditionBlock")
  209. def negation():
  210. core.set_mode("NegatorBlock")
  211. def link():
  212. core.set_mode("Link")
  213. def multiply():
  214. core.set_mode("MultiplyBlock")
  215. def constant():
  216. core.set_mode("ConstantBlock")
  217. def inverse():
  218. core.set_mode("InverseBlock")
  219. def ic():
  220. core.set_mode("InitialCondition")
  221. def delay():
  222. core.set_mode("DelayBlock")
  223. Button(root, text="+", command=addition).pack()
  224. Button(root, text="-x", command=negation).pack()
  225. Button(root, text="*", command=multiply).pack()
  226. Button(root, text="1/x", command=inverse).pack()
  227. Button(root, text="Constant", command=constant).pack()
  228. Button(root, text="Delay", command=delay).pack()
  229. Button(root, text="Link", command=link).pack()
  230. Button(root, text="InitialCondition", command=ic).pack()
  231. Button(root, text="SIM", command=simulate).pack()
  232. Button(root, text="STEP", command=step).pack()
  233. Button(root, text="PAUSE", command=pause).pack()
  234. core.canvas = canvas
  235. for i in range(JUMP, MAX_HEIGHT, JUMP):
  236. canvas.create_line(0, i, MAX_HEIGHT, i, fill="grey")
  237. for i in range(JUMP, MAX_WIDTH, JUMP):
  238. canvas.create_line(i, 0, i, MAX_WIDTH, fill="grey")
  239. canvas.bind("<Button-1>", clicked)
  240. canvas.bind("<Button-3>", draw)
  241. canvas.bind("<ButtonRelease-3>", release)
  242. visual = Toplevel(root)
  243. probes = {}
  244. values = {}
  245. #simulation = [(1, {"a": 1, "b": 2}), (2, {"a": 3}), (3, {"a": 4, "b": 6})]
  246. def update_graphs():
  247. while simulation:
  248. t, results = simulation.pop(0)
  249. for k, v in results.items():
  250. if k in probes:
  251. fcanvas, a = probes[k]
  252. else:
  253. f = Figure(figsize=(5,5), dpi=100)
  254. a = f.add_subplot(111)
  255. a.plot([], [])
  256. fcanvas = FigureCanvasTkAgg(f, visual)
  257. fcanvas.show()
  258. fcanvas.get_tk_widget().pack()
  259. probes[k] = (fcanvas, a)
  260. values[k] = ([], [])
  261. values[k][0].append(t)
  262. values[k][1].append(v)
  263. a.clear()
  264. a.plot(values[k][0], values[k][1], linestyle="none", marker="o")
  265. fcanvas.draw()
  266. root.after(50, update_graphs)
  267. root.after(50, update_graphs)
  268. root.mainloop()