adeireader.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. print 'ADEIReader initialized'
  39. def qurl(self, qtype, **kargs):
  40. url = self.host
  41. if qtype == 'get':
  42. url = url + 'getdata.php?'
  43. elif qtype == 'group':
  44. url = url + 'list.php?target=groups'
  45. elif qtype == 'sensor':
  46. url = url + 'list.php?target=items'
  47. kargs['db_server'] = self.server
  48. kargs['db_name'] = self.db
  49. kargs['window'] = kargs.get('window') or '-1'
  50. kargs['resample'] = kargs.get('resample') or '0'
  51. for k, v in kargs.iteritems():
  52. url += '&' + k + '=' + v
  53. return url
  54. def get_sensor_list(self):
  55. url = self.qurl('group')
  56. groups = [ v.get('db_group') for v in parse_xml(url) ]
  57. sensor_list = {}
  58. for g in groups:
  59. url = self.qurl('sensor', db_group=g)
  60. sensor_list[g] = { v['name']:v['value'] for v in parse_xml(url) }
  61. return sensor_list
  62. def getdata(self, group, *sensors):
  63. ' Fetch data from ADEI server. '
  64. if not self._sensors:
  65. self._sensors = self.get_sensor_list()
  66. try:
  67. masks = map(self._sensors.get(group).get, sensors)
  68. data = self.querydata(group, *masks)
  69. data[0] = ('timestamp', adei_timestamp(data[0][1]))
  70. except:
  71. data = []
  72. return data
  73. def querydata(self, group, *masks):
  74. masks = ','.join(map(str, masks))
  75. url = self.qurl('get', db_group=group, db_mask=masks)
  76. return parse_csv(url)
  77. @property
  78. def sensors(self):
  79. if not self._sensors:
  80. print 'retrieve sensor list'
  81. self._sensors = self.get_sensor_list()
  82. return self._sensors
  83. ###### Deprected #######
  84. def query(self, qtype='get', **kargs):
  85. # parse args
  86. group = str(kargs.get('group', ''))
  87. sensor = kargs.get('sensor', [])
  88. window = kargs.get('window','-1')
  89. resample = kargs.get('resample','0')
  90. sensor_mask = ','.join(map(str, sensor))
  91. url = self.qurl('get', db_group=group, db_mask=sensor_mask, window=window, resample=resample)
  92. data = parse_csv(url)
  93. # build sensor list
  94. #sensorlist = [ group+'__'+s for s in sensorMaskList ]
  95. #sensorlist.insert(0, 'timestamp')
  96. # pack data
  97. sname = [d[0] for d in data]
  98. svalue = [list( d[1:] ) for d in data]
  99. print svalue, len(svalue)
  100. svalue[0] = map(adei_timestamp, svalue[0])
  101. svalue = transpose_list(svalue)
  102. # resample data
  103. if resample != '0':
  104. res_value = [svalue[0]]
  105. t0 = svalue[0][0]
  106. for v in svalue:
  107. if v[0] - t0 >= resample:
  108. res_value.append(v)
  109. t0 = v[0]
  110. svalue = res_value
  111. # debug info
  112. if DEBUG == 1:
  113. #import pprint
  114. print '--------------------------------------------------'
  115. print url
  116. print 'data:', len(data), data[0]
  117. print 'sensor names', sname, len(sname)
  118. print 'sensor values', svalue, len(svalue[0])
  119. print 'sensor', len(sensor)
  120. print
  121. return svalue
  122. #def parse_sensors(self, *sensors):
  123. #'''
  124. #Args:
  125. #sensors (list): a list of sensor identifiers
  126. #Return:
  127. #Description:
  128. #sensor identifiers can be one of the following two forms,
  129. #1) <group name>.<sensor name>,
  130. #2) (<group name>, <sensor name 1>, [<sensor name 2>, [...]]).
  131. #'''
  132. #if self.sensor_list is None:
  133. #self.sensor_list = self.get_sensor_list()
  134. #parsed_sensors = []
  135. #for item in sensors:
  136. #try:
  137. #m = re.match('(\w+).(\w+)', item)
  138. #if m:
  139. #grp, sns = m.group(1), (m.group(2),)
  140. #except TypeError:
  141. #grp, sns= item[0], item[1:]
  142. #parsed_sensors.append((grp, sns))
  143. #res = {}
  144. #for k, v in parsed_sensors:
  145. #try:
  146. #res[k].extend(v)
  147. #except:
  148. #res[k] = list(v)
  149. #for k, v in res.iteritems():
  150. #try:
  151. #res[k] = sorted([ int(self.sensor_list.get(k).get(s)) for s in v ])
  152. #except:
  153. #pass
  154. #return res
  155. ADEI_QUERY_STRING = {
  156. 'group': 'db_group',
  157. 'sensor': 'db_mask'
  158. }
  159. def f(x):
  160. x = str(x)
  161. result = []
  162. try:
  163. for part in x.split(','):
  164. if '-' in part:
  165. a, b = part.split('-')
  166. a, b = int(a), int(b)
  167. result.extend(range(a, b + 1))
  168. else:
  169. a = int(part)
  170. result.append(a)
  171. except:
  172. pass
  173. return map(str, result )
  174. def transpose_list(l):
  175. return map(list, zip(*l))
  176. class ADEIError(Exception):
  177. pass