IdeasXDatabaseManager.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. '''
  2. Title: IdeasXDatabaseManager Class
  3. Author: Tyler Berezowsky
  4. Description: The purpose of this class is to parse the general portions
  5. (non-extended) portions of HealthMessages from the IdeasX system. Parshing
  6. completed by auto-generated code from the Google Protocols project. Once
  7. parsed, the information is stored into an SQLite DB.
  8. Requirements:
  9. - This class needs to be expandable for different device types.
  10. ToDo:
  11. - Code should be updated to utilize QSqlQuery.execBatch
  12. '''
  13. from PyQt5 import QtSql
  14. import time
  15. import os
  16. try:
  17. from protocolbuffers import IdeasXMessages_pb2 as IdeasXMessages
  18. except ImportError:
  19. print("The python classes for IdeasX are missing. Try running the Makefile in" +
  20. "ideasX-messages.")
  21. class IdeasXDatabaseManager():
  22. def __init__(self, database_filename='IdeasX.db'):
  23. ''' Attempt to initialize database.
  24. '''
  25. self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
  26. self.db.setDatabaseName(database_filename)
  27. db_open = self.db.open()
  28. # check if DB exists
  29. #if not os.path.isfile('./'+database_filename):
  30. if True:
  31. if db_open:
  32. self.query = QtSql.QSqlQuery()
  33. self.query.exec("CREATE TABLE encoder(" +
  34. "module_id char(17) primary key, " +
  35. "state_of_charge int, " +
  36. "battery_voltage real, " +
  37. "rssi int, " +
  38. "firmware_version int, " +
  39. "hardware_version int, " +
  40. "ssid varchar(33), " +
  41. "bssid varchar(33), " +
  42. "active bool, " +
  43. "charging bool, " +
  44. "low_battery bool, " +
  45. "ota bool);")
  46. self.printError("Created database")
  47. else:
  48. self.printError("Failed to open/create database")
  49. # system exit
  50. else:
  51. self.printError("Database already exists")
  52. self.query = QtSql.QSqlQuery()
  53. # initalize parsers
  54. self.healthMessage = IdeasXMessages.HealthMessage()
  55. #self.dataMessageParser = IdeasXMessages.DataMessage()
  56. #self.commandMessageParser = IdeasXMessages.CommandMessage()
  57. def printError(self, error_msg):
  58. print("IdeasX Database Manager Error: " + error_msg)
  59. def printMsg(self, msg):
  60. print("IdeasX Database Manager: " + msg)
  61. def parseHealthMessage(self, msg):
  62. self.healthMessage.ParseFromString(msg)
  63. flagOTA = 0
  64. flagCharging = 0
  65. flagLb = 0
  66. flagActive = 0
  67. if self.healthMessage.state.ota:
  68. flagOTA = 1
  69. if self.healthMessage.state.charging:
  70. flagCharging = 1
  71. if self.healthMessage.state.lb:
  72. flagLb = 1
  73. if self.healthMessage.state.active:
  74. flagActive = 1
  75. update = self.query.exec("SELECT 1 FROM encoder WHERE module_id ='"+self.macToString(self.healthMessage.module_id)+"';")
  76. if self.query.next():
  77. update = self.query.exec_("UPDATE encoder "+
  78. "SET state_of_charge="+str(self.calculateSOC(self.healthMessage.soc))+","+
  79. "battery_voltage="+str(self.calculateVCell(self.healthMessage.vcell))+","+
  80. "firmware_version="+str(self.healthMessage.firmware)+","+
  81. "hardware_version="+str(self.healthMessage.hardware_version)+","+
  82. "rssi="+str(self.healthMessage.rssi)+","+
  83. "ssid='"+self.healthMessage.ssid+"',"+
  84. "bssid='"+self.healthMessage.bssid+"',"+
  85. "active="+str(flagActive)+","+
  86. "ota="+str(flagOTA)+","+
  87. "charging="+str(flagCharging)+","+
  88. "low_battery="+str(flagLb)+" "+
  89. "WHERE module_id='"+self.macToString(self.healthMessage.module_id)+"';")
  90. self.printMsg("Updated existing module fields " + self.macToString(self.healthMessage.module_id))
  91. else:
  92. update = self.query.exec_("INSERT INTO encoder VALUES("+
  93. "'"+self.macToString(self.healthMessage.module_id)+"',"+
  94. str(self.calculateSOC(self.healthMessage.soc))+","+
  95. str(self.calculateVCell(self.healthMessage.vcell))+","+
  96. str(self.healthMessage.rssi)+","+
  97. str(self.healthMessage.firmware)+","+
  98. str(self.healthMessage.hardware_version)+","+
  99. "'"+self.healthMessage.ssid+"',"+
  100. "'"+self.healthMessage.bssid+"',"+
  101. str(flagActive)+","+
  102. str(flagCharging)+","+
  103. str(flagLb)+","+
  104. str(flagOTA)+
  105. ");")
  106. self.printMsg("Created new module " + self.macToString(self.healthMessage.module_id))
  107. if update == False:
  108. self.printError("SQL operation failed!")
  109. def macToString(self, mac_bytes):
  110. ''' Convert uint8 byte string to "XX:XX:XX:XX:XX"
  111. '''
  112. mac_str = ""
  113. for byte in mac_bytes:
  114. mac_str = mac_str + format(byte, 'x') + ':'
  115. return mac_str[:-1].format('utf-8')
  116. def calculateVCell(self, raw_Vcell):
  117. return raw_Vcell*1.25e-3
  118. def calculateSOC(self, raw_SOC):
  119. return raw_SOC.to_bytes(2, 'big')[0]
  120. def clearDatabase(self):
  121. self.printError("Failed to delete database")
  122. if __name__ == '__main__':
  123. dbm = IdeasXDatabaseManager()
  124. msg = IdeasXMessages.HealthMessage()
  125. msg.module_id = bytes("1113321", 'utf-8')
  126. msg.rssi = -56
  127. msg.soc = 89
  128. msg.vcell = 54323
  129. msg.ssid = "Icaraus"
  130. msg.state.ota = False
  131. msg.state.lb = False
  132. msg.state.charging = False
  133. msg.state.active = False
  134. msg.auth = 0
  135. msg.firmware = 123
  136. msg.hardware_version = 1
  137. msg.rom = 0
  138. str_msg = msg.SerializeToString()
  139. dbm.parseHealthMessage(str_msg)
  140. # exit program