core.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. import os
  2. import sys
  3. import yaml
  4. import requests
  5. import shutil
  6. from datetime import date
  7. import csv
  8. import urllib2
  9. import re
  10. import tornado.escape
  11. import tornado.ioloop
  12. import tornado.web
  13. import tornado.autoreload
  14. from tornado.escape import json_decode
  15. from tornado.escape import json_encode
  16. from threading import Timer
  17. import collections
  18. root = os.path.dirname(__file__)
  19. with open("config.yaml", 'r') as stream:
  20. try:
  21. #print(yaml.load(stream))
  22. config = yaml.load(stream)
  23. except yaml.YAMLError as exc:
  24. print(exc)
  25. if config == None:
  26. print("Error: Empty configuration file.")
  27. sys.exit(1)
  28. class RepeatedTimer(object):
  29. def __init__(self, interval, function, *args, **kwargs):
  30. self._timer = None
  31. self.interval = interval
  32. self.function = function
  33. self.args = args
  34. self.kwargs = kwargs
  35. self.is_running = False
  36. self.start()
  37. def _run(self):
  38. self.is_running = False
  39. self.start()
  40. self.function(*self.args, **self.kwargs)
  41. def start(self):
  42. if not self.is_running:
  43. self._timer = Timer(self.interval, self._run)
  44. self._timer.start()
  45. self.is_running = True
  46. def stop(self):
  47. self._timer.cancel()
  48. self.is_running = False
  49. def setInterval(self, interval):
  50. self.interval = interval
  51. def fetchDataADEI():
  52. if os.path.isfile(config["path"]+".mutex"):
  53. #print("Process running...")
  54. return
  55. else:
  56. #print("Created mutex")
  57. file = open(config["path"]+'.mutex', 'w+')
  58. with open("varname.yaml", 'r') as stream:
  59. try:
  60. #print(yaml.load(stream))
  61. varname = yaml.load(stream)
  62. except yaml.YAMLError as exc:
  63. print(exc)
  64. if varname == None:
  65. print("Error: Empty varname file.")
  66. os.remove(config["path"]+".mutex")
  67. return
  68. cache_data = {}
  69. for param in varname:
  70. print param
  71. dest = config['server'] + config['script']
  72. url = dest + "?" + varname[param]
  73. print url
  74. data = requests.get(url,
  75. auth=(config['username'],
  76. config['password'])).content
  77. #tmp_data = data.content
  78. print data
  79. last_value = data.split(",")[-1].strip()
  80. try:
  81. print last_value
  82. test_x = float(last_value)
  83. except ValueError:
  84. last_value = None
  85. print last_value
  86. cache_data[param] = last_value
  87. with open(".tmp.yaml", 'w') as stream_tmp:
  88. stream_tmp.write(yaml.dump(cache_data, default_flow_style=False))
  89. src_file = config["path"] + ".tmp.yaml"
  90. dst_file = config["path"] + "cache.yaml"
  91. shutil.copy(src_file, dst_file)
  92. os.remove(config["path"]+".mutex")
  93. """
  94. with open("config.yaml", 'r') as stream:
  95. try:
  96. #print(yaml.load(stream))
  97. config = yaml.load(stream)
  98. except yaml.YAMLError as exc:
  99. print(exc)
  100. if config == None:
  101. print("Error: Empty configuration file.")
  102. sys.exit(1)
  103. """
  104. print "Start torrenting..."
  105. # it auto-starts, no need of rt.start()
  106. print "Debugging..."
  107. # TODO: Turn off for debug
  108. rt = RepeatedTimer(config["polling"], fetchDataADEI)
  109. class ListHandler(tornado.web.RequestHandler):
  110. def get(self):
  111. with open("cache.yaml", 'r') as stream:
  112. try:
  113. #print(yaml.load(stream))
  114. response = yaml.load(stream)
  115. except yaml.YAMLError as exc:
  116. print(exc)
  117. if response == None:
  118. response = {"error": "No data entry."}
  119. print response
  120. self.write(response)
  121. class StartHandler(tornado.web.RequestHandler):
  122. def get(self):
  123. print "Start fetchData"
  124. rt.start()
  125. class StopHandler(tornado.web.RequestHandler):
  126. def get(self):
  127. print "Stop fetchData"
  128. rt.stop()
  129. if os.path.isfile(config["path"]+".mutex"):
  130. os.remove(config["path"]+".mutex")
  131. class SetTimerHandler(tornado.web.RequestHandler):
  132. def get(self, duration):
  133. print "Set interval"
  134. rt.setInterval(float(duration))
  135. class DesignerHandler(tornado.web.RequestHandler):
  136. def get(self):
  137. print "In designer mode."
  138. with open("cache.yaml", 'r') as stream:
  139. try:
  140. #print(yaml.load(stream))
  141. cache_data = yaml.load(stream)
  142. except yaml.YAMLError as exc:
  143. print(exc)
  144. if cache_data == None:
  145. print("Error: Empty cache data file.")
  146. return
  147. print cache_data
  148. with open("style.yaml", 'r') as stream:
  149. try:
  150. #print(yaml.load(stream))
  151. style_data = yaml.load(stream)
  152. except yaml.YAMLError as exc:
  153. print(exc)
  154. data = {
  155. "cache": cache_data,
  156. "style": style_data
  157. }
  158. self.render('designer.html', data=data)
  159. class VersionHandler(tornado.web.RequestHandler):
  160. def get(self):
  161. response = {'version': '0.0.1',
  162. 'last_build': date.today().isoformat()}
  163. self.write(response)
  164. class SaveHandler(tornado.web.RequestHandler):
  165. def post(self):
  166. print self.request.body
  167. json_obj = json_decode(self.request.body)
  168. print('Post data received')
  169. with open("style.yaml", 'w') as output:
  170. output.write(yaml.safe_dump(json_obj, encoding='utf-8', allow_unicode=True, default_flow_style=False))
  171. response = {"success": "Data entry inserted."}
  172. #self.write(json.dumps(response))
  173. class StatusHandler(tornado.web.RequestHandler):
  174. def get(self):
  175. print "In status mode."
  176. with open("style.yaml", 'r') as stream:
  177. try:
  178. #print(yaml.load(stream))
  179. style_data = yaml.load(stream)
  180. except yaml.YAMLError as exc:
  181. print(exc)
  182. if style_data == None:
  183. print("Error: Empty style data file.")
  184. return
  185. data = {
  186. "style": style_data
  187. }
  188. self.render('status.html', data=data)
  189. class AdeiKatrinHandler(tornado.web.RequestHandler):
  190. def get(self, **params):
  191. #print params
  192. sensor_name = str(params["sensor_name"])
  193. """
  194. {'db_group': u'320_KRY_Kryo_4K_CurLead',
  195. 'db_name': u'ControlSystem_CPS',
  196. 'sensor_name': u'320-RTP-8-1103',
  197. 'db_server': u'cscps',
  198. 'control_group': u'320_KRY_Kryo_3K'}
  199. """
  200. if config["type"] != "adei":
  201. print("Error: Wrong handler.")
  202. return
  203. #print config
  204. dest = config['server'] + config['script']
  205. query_cmds = []
  206. query_cmds.append("db_server="+str(params['db_server']))
  207. query_cmds.append("db_name="+str(params['db_name']))
  208. query_cmds.append("db_group="+str(params['db_group']))
  209. query_cmds.append("db_mask=all")
  210. query_cmds.append("window=-1")
  211. query = "&".join(query_cmds)
  212. url = dest + "?" + query
  213. #print url
  214. # get the db_masks
  215. # store the query command in varname
  216. data = requests.get(url, auth=(config['username'], config['password']))
  217. cr = data.content
  218. cr = cr.split(",")
  219. print cr, len(cr)
  220. # parameter name stored in ADEI with '-IST_Val' suffix
  221. match_token = params['sensor_name'] + "-IST_Val"
  222. db_mask = None
  223. for i, item in enumerate(cr):
  224. if "[" and "]" in item.strip():
  225. lhs = re.match(r"[^[]*\[([^]]*)\]", item.strip()).groups()[0]
  226. if lhs == params['sensor_name']:
  227. db_mask = i - 1
  228. else:
  229. if item.strip() == match_token:
  230. db_mask = i - 1
  231. if db_mask == None:
  232. response = {"Error": "Cannot find variable on ADEI server."}
  233. self.write(response)
  234. return
  235. query_cmds.append("db_mask="+str(db_mask))
  236. query = "&".join(query_cmds)
  237. # column name available
  238. # store in yaml file
  239. with open("varname.yaml", 'r') as stream:
  240. try:
  241. #print(yaml.load(stream))
  242. cache_data = yaml.load(stream)
  243. except yaml.YAMLError as exc:
  244. print(exc)
  245. #print "CHECK THIS"
  246. #print sensor_name, query
  247. #print cache_data
  248. if cache_data == None:
  249. cache_data = {}
  250. cache_data[sensor_name] = query
  251. else:
  252. if sensor_name not in cache_data:
  253. cache_data[sensor_name] = query
  254. else:
  255. response = {"Error": "Variable already available in varname file."}
  256. self.write(response)
  257. return
  258. with open("varname.yaml", 'w') as output:
  259. output.write(yaml.dump(cache_data, default_flow_style=False))
  260. response = {"success": "Data entry inserted."}
  261. #print match_token, db_mask
  262. self.write(response)
  263. class GetDataHandler(tornado.web.RequestHandler):
  264. def get(self):
  265. with open("cache.yaml", 'r') as stream:
  266. try:
  267. #print(yaml.load(stream))
  268. cache_data = yaml.load(stream)
  269. except yaml.YAMLError as exc:
  270. print(exc)
  271. print("GetData:")
  272. if cache_data == None:
  273. cache_data = {}
  274. print cache_data
  275. self.write(cache_data)
  276. application = tornado.web.Application([
  277. (r"/version", VersionHandler),
  278. (r"/list", ListHandler),
  279. (r"/start", StartHandler),
  280. (r"/stop", StopHandler),
  281. (r"/designer", DesignerHandler),
  282. (r"/status", StatusHandler),
  283. (r"/save/", SaveHandler),
  284. (r"/getdata/", GetDataHandler),
  285. (r"/timer/(?P<duration>[^\/]+)/?", SetTimerHandler),
  286. (r"/add/(?P<db_server>[^\/]+)/?(?P<db_name>[^\/]+)/?(?P<db_group>[^\/]+)/?(?P<sensor_name>[^\/]+)?", AdeiKatrinHandler)
  287. ], debug=True, static_path=os.path.join(root, 'static'), js_path=os.path.join(root, 'js'))
  288. if __name__ == "__main__":
  289. application.listen(8888)
  290. tornado.autoreload.start()
  291. #tornado.autoreload.watch('myfile')
  292. tornado.ioloop.IOLoop.instance().start()