Guest User

Untitled

a guest
Sep 7th, 2025
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.40 KB | None | 0 0
  1. #!/bin/python
  2.  
  3. import pkg_resources, sqlite3, subprocess, sys, time
  4. from datetime import datetime
  5. from datetime import timedelta
  6.  
  7. required = {'requests'}
  8. installed = {pkg.key for pkg in pkg_resources.working_set}
  9. missing = required - installed
  10.  
  11. if missing:
  12. subprocess.check_call([sys.executable, '-m', 'pip', 'install', *missing])
  13.  
  14. import requests
  15.  
  16. # Local Home Assistant API access URL
  17. url = 'http://homeassistant.local:8123/api/states/sensor.'
  18.  
  19. # The one and only... long lasting token!
  20. headers = {
  21. 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIyZmI3Nzg3OTEwNDE0NTZkYWNlMzExMWVkYmUxMjhiNyIsImlhdCI6MTY5NzM2Nzg1OSwiZXhwIjoyMDEyNzI3ODU5fQ.05mfSBnhZm0LxBdEZOBEjDU3OKHI7A0iNmecYhznY1Y',
  22. 'content-type': 'application/json'
  23. }
  24.  
  25. # Some dates and math for the steps sensor
  26. today = datetime.now()
  27.  
  28. startDay = today.strftime('%Y-%m-%d 00:00:00')
  29. startDayX = time.mktime(datetime.strptime(startDay, "%Y-%m-%d %H:%M:%S").timetuple())
  30.  
  31. endDay = today.strftime('%Y-%m-%d 23:59:59')
  32. endDayX = time.mktime(datetime.strptime(endDay, "%Y-%m-%d %H:%M:%S").timetuple())
  33.  
  34. # SQLite database location
  35. db_path = "/media/Drive/Gadgetbridge.db"
  36.  
  37. # Connect to the database
  38. conn = sqlite3.connect(db_path)
  39. cursor = conn.cursor()
  40.  
  41. # SQLite query to retrieve the total steps for the current day and put this into a variable
  42. steps_query = f"SELECT SUM(STEPS) as Steps FROM KEEP_FIT_ACTIVITY_SAMPLE WHERE TIMESTAMP BETWEEN {startDayX} AND {endDayX};"
  43. cursor.execute(steps_query)
  44. daily_steps = int(cursor.fetchone()[0] or 0)
  45.  
  46. print("Daily steps data has been saved: " + str(daily_steps))
  47.  
  48. # SQLite query to retrieve the most recent heart rate value and put this into a variable
  49. heart_rate_query = f"SELECT HEART_RATE FROM KEEP_FIT_HEART_RATE_SAMPLE WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  50. cursor.execute(heart_rate_query)
  51. try:
  52. current_heart_rate = int(cursor.fetchone()[0] or 0)
  53. except:
  54. current_heart_rate = 0
  55.  
  56. print("Current heart rate data has been saved: " + str(current_heart_rate))
  57.  
  58. # SQLite query to retrieve the most recent heart rate value and put this into a variable
  59. spo2_query = f"SELECT SPO2 FROM KEEP_FIT_SPO2_SAMPLE WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  60. cursor.execute(spo2_query)
  61. try:
  62. current_spo2 = int(cursor.fetchone()[0] or 0)
  63. except:
  64. current_spo2 = 0
  65.  
  66. print("Current spo2 data has been saved: " + str(current_spo2))
  67.  
  68. # SQLite query to retrieve the most recent stress value and put this into a variable
  69. stress_query = f"SELECT STRESS FROM KEEP_FIT_STRESS_SAMPLE WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  70. cursor.execute(stress_query)
  71. try:
  72. current_stress = int(cursor.fetchone()[0] or 0)
  73. except:
  74. current_stress = 0
  75.  
  76. print("Current stress level data has been saved: " + str(current_stress))
  77.  
  78. # SQLite query to retrieve the most recent diastolic blood pressure value and put this into a variable
  79. bp_diastolic_query = f"SELECT BP_DIASTOLIC FROM KEEP_FIT_BLOOD_PRESSURE_SAMPLE WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  80. cursor.execute(bp_diastolic_query)
  81. try:
  82. current_bp_diastolic = int(cursor.fetchone()[0] or 0)
  83. except:
  84. current_bp_diastolic = 0
  85.  
  86. print("Current diastolic blood pressure data has been saved: " + str(current_bp_diastolic))
  87.  
  88. # SQLite query to retrieve the most recent systolic blood pressure value and put this into a variable
  89. bp_systolic_query = f"SELECT BP_SYSTOLIC FROM KEEP_FIT_BLOOD_PRESSURE_SAMPLE WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  90. cursor.execute(bp_systolic_query)
  91. try:
  92. current_bp_systolic = int(cursor.fetchone()[0] or 0)
  93. except:
  94. current_bp_systolic = 0
  95.  
  96. print("Current systolic blood pressure data has been saved: " + str(current_bp_systolic))
  97.  
  98. # SQLite query to retrieve the most recent sleep score value and put this into a variable
  99. sleep_score_query = f"SELECT SLEEP_SCORE FROM KEEP_FIT_SLEEP_SAMPLE WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  100. cursor.execute(sleep_score_query)
  101. try:
  102. current_sleep_score = int(cursor.fetchone()[0] or 0)
  103. except:
  104. current_sleep_score = 0
  105.  
  106. print("Current sleep score data has been saved: " + str(current_sleep_score))
  107.  
  108. # SQLite query to retrieve the most recent battery level value and put this into a variable
  109. battery_level_query = f"SELECT LEVEL FROM BATTERY_LEVEL WHERE TIMESTAMP ORDER BY TIMESTAMP DESC;"
  110. cursor.execute(battery_level_query)
  111. try:
  112. current_battery_level = int(cursor.fetchone()[0] or 0)
  113. except:
  114. current_battery_level = 0
  115.  
  116. print("Current battery level data has been saved: " + str(current_battery_level))
  117.  
  118. # SQLite query to retrieve data about the gadget and put them into variables
  119. device_name_query = f"SELECT NAME FROM DEVICE;"
  120. cursor.execute(device_name_query)
  121. try:
  122. device_name = cursor.fetchone()[0]
  123. except:
  124. device_name = "None"
  125.  
  126. device_type_query = f"SELECT TYPE_NAME FROM DEVICE;"
  127. cursor.execute(device_type_query)
  128. try:
  129. device_type = cursor.fetchone()[0]
  130. except:
  131. device_type = "None"
  132.  
  133. device_manufacturer_query = f"SELECT MANUFACTURER FROM DEVICE;"
  134. cursor.execute(device_manufacturer_query)
  135. try:
  136. device_manufacturer = cursor.fetchone()[0]
  137. except:
  138. device_manufacturer = "None"
  139.  
  140. device_identifier_query = f"SELECT IDENTIFIER FROM DEVICE;"
  141. cursor.execute(device_identifier_query)
  142. try:
  143. device_identifier = cursor.fetchone()[0]
  144. except:
  145. device_identifier = "None"
  146.  
  147. device_firmware_query = f"SELECT FIRMWARE_VERSION1 FROM DEVICE_ATTRIBUTES ORDER BY _id DESC;"
  148. cursor.execute(device_firmware_query)
  149. temp_fw_ver = cursor.fetchall()
  150.  
  151. if (temp_fw_ver[0])[0] =='':
  152. device_firmware = (temp_fw_ver[0])[1]
  153. else:
  154. device_firmware = (temp_fw_ver[0])[0]
  155.  
  156. print("Current device data has been saved. Name: " + str(device_name) + ", Type: " + str(device_type) + ", Manufacturer: " + str(device_manufacturer) + ", Identifier: " + str(device_identifier) + ", Firmware: " + str(device_firmware))
  157.  
  158. # After all data is extracted, close the connection to the database again
  159. conn.close()
  160.  
  161. # Get the extracted data into Home Assistant
  162. errors = ''
  163.  
  164. # sensor names
  165. variable1 = 'ring_schritte_heute'
  166. variable2 = 'ring_puls'
  167. variable3 = 'ring_spo2'
  168. variable4 = 'ring_stresswert'
  169. variable5 = 'ring_blutdruck_systolisch'
  170. variable6 = 'ring_blutdruck_diastolisch'
  171. variable7 = 'ring_schlafwert'
  172. variable8 = 'ring_batterie'
  173. variable9 = 'ring_geraet'
  174.  
  175. attributes1 = '{"unit_of_measurement": "steps", "state_class": "total_increasing", "friendly_name": "Ring Schritte heute", "icon": "mdi:walk"}'
  176. attributes2 = '{"unit_of_measurement": "bpm", "state_class": "measurement", "friendly_name": "Ring Puls", "icon": "mdi:heart-pulse"}'
  177. attributes3 = '{"unit_of_measurement": "%", "state_class": "measurement", "friendly_name": "Ring SpO2", "icon": "mdi:water-plus"}'
  178. attributes4 = '{"friendly_name": "Ring Stresswert", "icon": "mdi:pulse"}'
  179. attributes5 = '{"unit_of_measurement": "mmHg", "device_class": "pressure", "friendly_name": "Ring systolischer Blutdruck", "icon": "mdi:heart-pulse"}'
  180. attributes6 = '{"unit_of_measurement": "mmHg", "device_class": "pressure", "friendly_name": "Ring diastolischer Blutdruck", "icon": "mdi:heart-pulse"}'
  181. attributes7 = '{"friendly_name": "Ring Schlafwert", "icon": "mdi:sleep"}'
  182. attributes8 = '{"unit_of_measurement": "%", "state_class": "measurement", "device_class": "battery", "friendly_name": "Ring Batteriestand", "icon": "mdi:battery"}'
  183. attributes9 = '{"device_name": "' + str(device_name) + '", "device_type": "' + str(device_type) + '", "device_manufacturer": "' + str(device_manufacturer) + '", "device_identifier": "' + str(device_identifier) + '", "device_firmware": "' + str(device_firmware) + '", "friendly_name": "Ring Geräteinformationen", "icon": "mdi:devices"}'
  184.  
  185. # Prepare the data
  186. data1 = '{"state": "' + str(daily_steps) + '", "attributes": ' + attributes1 + '}'
  187. data1 = data1.replace("'",'"')
  188. data2 = '{"state": "' + str(current_heart_rate) + '", "attributes": ' + attributes2 + '}'
  189. data2 = data2.replace("'",'"')
  190. data3 = '{"state": "' + str(current_spo2) + '", "attributes": ' + attributes3 + '}'
  191. data3 = data3.replace("'",'"')
  192. data4 = '{"state": "' + str(current_stress) + '", "attributes": ' + attributes4 + '}'
  193. data4 = data4.replace("'",'"')
  194. data5 = '{"state": "' + str(current_bp_systolic) + '", "attributes": ' + attributes5 + '}'
  195. data5 = data5.replace("'",'"')
  196. data6 = '{"state": "' + str(current_bp_diastolic) + '", "attributes": ' + attributes6 + '}'
  197. data6 = data6.replace("'",'"')
  198. data7 = '{"state": "' + str(current_sleep_score) + '", "attributes": ' + attributes7 + '}'
  199. data7 = data7.replace("'",'"')
  200. data8 = '{"state": "' + str(current_battery_level) + '", "attributes": ' + attributes8 + '}'
  201. data8 = data8.replace("'",'"')
  202. data9 = '{"state": "' + str(device_name) + '", "attributes": ' + attributes9 + '}'
  203. data9 = data9.replace("'",'"')
  204.  
  205. # Get data into sensors via API
  206. r1 = requests.post(url+variable1, data=data1, headers=headers)
  207. if r1.status_code != 200 and r1.status_code != 201:
  208. errors = errors + 'ERROR:' + variable1 + ' - ' + str(r1.status_code)
  209.  
  210. r2 = requests.post(url+variable2, data=data2, headers=headers)
  211. if r2.status_code != 200 and r2.status_code != 201:
  212. errors = errors + 'ERROR:' + variable2 + ' - ' + str(r2.status_code)
  213.  
  214. r3 = requests.post(url+variable3, data=data3, headers=headers)
  215. if r3.status_code != 200 and r3.status_code != 201:
  216. errors = errors + 'ERROR:' + variable3 + ' - ' + str(r3.status_code)
  217.  
  218. r4 = requests.post(url+variable4, data=data4, headers=headers)
  219. if r4.status_code != 200 and r4.status_code != 201:
  220. errors = errors + 'ERROR:' + variable4 + ' - ' + str(r4.status_code)
  221.  
  222. r5 = requests.post(url+variable5, data=data5, headers=headers)
  223. if r5.status_code != 200 and r5.status_code != 201:
  224. errors = errors + 'ERROR:' + variable5 + ' - ' + str(r5.status_code)
  225.  
  226. r6 = requests.post(url+variable6, data=data6, headers=headers)
  227. if r6.status_code != 200 and r6.status_code != 201:
  228. errors = errors + 'ERROR:' + variable6 + ' - ' + str(r6.status_code)
  229.  
  230. r7 = requests.post(url+variable7, data=data7, headers=headers)
  231. if r7.status_code != 200 and r7.status_code != 201:
  232. errors = errors + 'ERROR:' + variable7 + ' - ' + str(r7.status_code)
  233.  
  234. r8 = requests.post(url+variable8, data=data8, headers=headers)
  235. if r8.status_code != 200 and r8.status_code != 201:
  236. errors = errors + 'ERROR:' + variable8 + ' - ' + str(r8.status_code)
  237.  
  238. r9 = requests.post(url+variable9, data=data9, headers=headers)
  239. if r9.status_code != 200 and r9.status_code != 201:
  240. errors = errors + 'ERROR:' + variable9 + ' - ' + str(r9.status_code)
  241.  
Advertisement
Add Comment
Please, Sign In to add comment