adeireader.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import datetime
  4. import calendar
  5. import urllib2 as urllib
  6. import base64
  7. from helper import csvparser, xmlparser, print_exc
  8. import re
  9. from itertools import groupby
  10. DEBUG = 0
  11. ADEI_Time_Format = '%d-%b-%y %H:%M:%S.%f'
  12. def adei_timestamp(adeitimestr):
  13. timestamp = datetime.datetime.strptime(adeitimestr, ADEI_Time_Format)
  14. timestamp = calendar.timegm(timestamp.timetuple())
  15. return timestamp
  16. def parse_csv(url, username=None, password=None):
  17. request = urllib.Request(url)
  18. base64string = base64.encodestring('%s:%s' % ( username, password ) )
  19. request.add_header("Authorization", "Basic %s" % base64string)
  20. fp = urllib.urlopen(request)
  21. resp = csvparser(fp)
  22. #stamps = map(adei_timestamp, resp[0][1:])
  23. #data = [dict(zip(('name', 'values'), [s[0], s[1:]])) for s in resp[1:]]
  24. return resp
  25. #return stamps, data
  26. def parse_xml(url, username=None, password=None):
  27. request = urllib.Request(url)
  28. base64string = base64.encodestring('%s:%s' % ( username, password ) )
  29. request.add_header("Authorization", "Basic %s" % base64string)
  30. fp = urllib.urlopen(request)
  31. return xmlparser(fp)
  32. class ADEIReader(object):
  33. def __init__(self, host, server, db):
  34. self.host = host + '/services/'
  35. self.server = server
  36. self.db = db
  37. # self._sensors = None
  38. self._sensors = self.get_sensor_list()
  39. # print 'ADEIReader initialized'
  40. def qurl(self, qtype, **kargs):
  41. url = self.host
  42. if qtype == 'get':
  43. url = url + 'getdata.php?'
  44. elif qtype == 'group':
  45. url = url + 'list.php?target=groups'
  46. elif qtype == 'sensor':
  47. url = url + 'list.php?target=items'
  48. kargs['db_server'] = self.server
  49. kargs['db_name'] = self.db
  50. kargs['window'] = kargs.get('window') or '-1'
  51. kargs['resample'] = kargs.get('resample') or '0'
  52. for k, v in kargs.iteritems():
  53. url += '&' + k + '=' + v
  54. return url
  55. def get_sensor_list(self):
  56. url = self.qurl('group')
  57. groups = [ v.get('db_group') for v in parse_xml(url) ]
  58. sensor_list = {}
  59. for g in groups:
  60. url = self.qurl('sensor', db_group=g)
  61. sensor_list[g] = { v['name']:v['value'] for v in parse_xml(url) }
  62. return sensor_list
  63. def getdata(self, group, *sensors):
  64. ' Fetch data from ADEI server. '
  65. try:
  66. masks = map(int, sensors)
  67. except:
  68. if not self._sensors:
  69. self._sensors = self.get_sensor_list()
  70. if group in self._sensors:
  71. masks = map(self._sensors.get(group).get, sensors)
  72. else:
  73. masks = []
  74. if masks:
  75. try:
  76. data = self.querydata(group, *masks)
  77. data[0] = ('timestamp', adei_timestamp(data[0][1]))
  78. except:
  79. data = []
  80. else:
  81. data = []
  82. return data
  83. def querydata(self, group, *masks):
  84. masks = ','.join(map(str, masks))
  85. url = self.qurl('get', db_group=group, db_mask=masks)
  86. return parse_csv(url)
  87. @property
  88. def sensors(self):
  89. # if not self._sensors:
  90. # print 'retrieve sensor list'
  91. # self._sensors = self.get_sensor_list()
  92. return self._sensors
  93. ###### Deprected #######
  94. def query(self, qtype='get', **kargs):
  95. # parse args
  96. group = str(kargs.get('group', ''))
  97. sensor = kargs.get('sensor', [])
  98. window = kargs.get('window','-1')
  99. resample = kargs.get('resample','0')
  100. sensor_mask = ','.join(map(str, sensor))
  101. url = self.qurl('get', db_group=group, db_mask=sensor_mask, window=window, resample=resample)
  102. data = parse_csv(url)
  103. # build sensor list
  104. #sensorlist = [ group+'__'+s for s in sensorMaskList ]
  105. #sensorlist.insert(0, 'timestamp')
  106. # pack data
  107. sname = [d[0] for d in data]
  108. svalue = [list( d[1:] ) for d in data]
  109. print svalue, len(svalue)
  110. svalue[0] = map(adei_timestamp, svalue[0])
  111. svalue = transpose_list(svalue)
  112. # resample data
  113. if resample != '0':
  114. res_value = [svalue[0]]
  115. t0 = svalue[0][0]
  116. for v in svalue:
  117. if v[0] - t0 >= resample:
  118. res_value.append(v)
  119. t0 = v[0]
  120. svalue = res_value
  121. # debug info
  122. if DEBUG == 1:
  123. #import pprint
  124. print '--------------------------------------------------'
  125. print url
  126. print 'data:', len(data), data[0]
  127. print 'sensor names', sname, len(sname)
  128. print 'sensor values', svalue, len(svalue[0])
  129. print 'sensor', len(sensor)
  130. print
  131. return svalue
  132. #def parse_sensors(self, *sensors):
  133. #'''
  134. #Args:
  135. #sensors (list): a list of sensor identifiers
  136. #Return:
  137. #Description:
  138. #sensor identifiers can be one of the following two forms,
  139. #1) <group name>.<sensor name>,
  140. #2) (<group name>, <sensor name 1>, [<sensor name 2>, [...]]).
  141. #'''
  142. #if self.sensor_list is None:
  143. #self.sensor_list = self.get_sensor_list()
  144. #parsed_sensors = []
  145. #for item in sensors:
  146. #try:
  147. #m = re.match('(\w+).(\w+)', item)
  148. #if m:
  149. #grp, sns = m.group(1), (m.group(2),)
  150. #except TypeError:
  151. #grp, sns= item[0], item[1:]
  152. #parsed_sensors.append((grp, sns))
  153. #res = {}
  154. #for k, v in parsed_sensors:
  155. #try:
  156. #res[k].extend(v)
  157. #except:
  158. #res[k] = list(v)
  159. #for k, v in res.iteritems():
  160. #try:
  161. #res[k] = sorted([ int(self.sensor_list.get(k).get(s)) for s in v ])
  162. #except:
  163. #pass
  164. #return res
  165. ADEI_QUERY_STRING = {
  166. 'group': 'db_group',
  167. 'sensor': 'db_mask'
  168. }
  169. def f(x):
  170. x = str(x)
  171. result = []
  172. try:
  173. for part in x.split(','):
  174. if '-' in part:
  175. a, b = part.split('-')
  176. a, b = int(a), int(b)
  177. result.extend(range(a, b + 1))
  178. else:
  179. a = int(part)
  180. result.append(a)
  181. except:
  182. pass
  183. return map(str, result )
  184. def transpose_list(l):
  185. return map(list, zip(*l))
  186. class ADEIError(Exception):
  187. pass