getData.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import asyncio
  2. from bleak import BleakClient, BleakScanner
  3. from bleak.backends.characteristic import BleakGATTCharacteristic
  4. import struct
  5. import sqlite3
  6. from dotenv import load_dotenv
  7. import os
  8. import smbus2
  9. import bme280
  10. # Initialise the BME280
  11. port = 1
  12. address = 0x76
  13. bus = smbus2.SMBus(port)
  14. calibration_params = bme280.load_calibration_params(bus, address)
  15. load_dotenv()
  16. outdoorName = os.getenv("BLE_PERIPHERAL_NAME")
  17. outdoorConnected = 0
  18. TEMP_UUID = "2A6E"
  19. PRESSURE_UUID = "2A6D"
  20. HUMIDITY_UUID = "2A6F"
  21. ALTITUDE_UUID = "2AB3"
  22. indoorValues = {
  23. "Temperature": 0,
  24. "Pressure": 0,
  25. "Humidity": 0,
  26. "Altitude": 0,
  27. }
  28. outdoorValues = {
  29. "Temperature": 0,
  30. "Pressure": 0,
  31. "Humidity": 0,
  32. "Altitude": 0,
  33. }
  34. def notification_handler(characteristic: BleakGATTCharacteristic, data: bytearray):
  35. global outdoorValues
  36. outdoorValues[characteristic.description] = struct.unpack("<i", data)[0]
  37. async def ble_task():
  38. global outdoorConnected
  39. while True:
  40. device = await BleakScanner.find_device_by_name(outdoorName)
  41. if device is None:
  42. outdoorConnected = 0
  43. print("no device found, wait then scan again")
  44. await asyncio.sleep(10)
  45. continue
  46. try:
  47. async with BleakClient(device) as client:
  48. outdoorConnected = 1
  49. print(f"connected to {outdoorName}")
  50. await client.start_notify(TEMP_UUID, notification_handler)
  51. await client.start_notify(PRESSURE_UUID, notification_handler)
  52. await client.start_notify(HUMIDITY_UUID, notification_handler)
  53. await client.start_notify(ALTITUDE_UUID, notification_handler)
  54. except Exception:
  55. outdoorConnected = 0
  56. print("exception while connecting or getting data")
  57. async def sensor_task():
  58. global indoorValues
  59. while True:
  60. data = bme280.sample(bus, address, calibration_params)
  61. indoorValues["Temperature"] = round(data.temperature * 100)
  62. indoorValues["Pressure"] = round(data.pressure * 100)
  63. indoorValues["Humidity"] = round(data.humidity * 100)
  64. indoorValues["Altitude"] = 0 # * 100
  65. await asyncio.sleep(1)
  66. conn = sqlite3.connect('./data/meteostanica.sqlite')
  67. cursor = conn.cursor()
  68. cursor.execute(
  69. """CREATE TABLE IF NOT EXISTS data (
  70. timestamp datetime default current_timestamp primary key,
  71. indoorTemp text not null,
  72. indoorPressure text not null,
  73. indoorHumidity text not null,
  74. indoorAltitude text not null,
  75. outdoorConnected integer not null,
  76. outdoorTemp text not null,
  77. outdoorPressure text not null,
  78. outdoorHumidity text not null,
  79. outdoorAltitude text not null
  80. );"""
  81. )
  82. conn.commit()
  83. async def write_task():
  84. while True:
  85. cursor.execute(f"""INSERT INTO data (
  86. 'indoorTemp', 'indoorPressure', 'indoorHumidity', 'indoorAltitude', 'outdoorConnected', 'outdoorTemp', 'outdoorPressure', 'outdoorHumidity', 'outdoorAltitude'
  87. ) VALUES (
  88. ?, ?, ?, ?, ?, ?, ?, ?, ?
  89. )""",
  90. (
  91. indoorValues["Temperature"],
  92. indoorValues["Pressure"],
  93. indoorValues["Humidity"],
  94. indoorValues["Altitude"],
  95. outdoorConnected,
  96. outdoorValues["Temperature"],
  97. outdoorValues["Pressure"],
  98. outdoorValues["Humidity"],
  99. outdoorValues["Altitude"]
  100. ))
  101. conn.commit()
  102. print(f"indoor: {indoorValues["Temperature"] / 100}°C, outdoor: {outdoorConnected} - {outdoorValues["Temperature"] / 100}°C")
  103. await asyncio.sleep(10)
  104. async def main():
  105. try:
  106. t1 = asyncio.create_task(ble_task())
  107. t2 = asyncio.create_task(sensor_task())
  108. t3 = asyncio.create_task(write_task())
  109. await asyncio.gather(t1, t2, t3)
  110. except asyncio.exceptions.CancelledError:
  111. pass
  112. asyncio.run(main())