getData.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. from smbus2 import SMBus
  9. from bme280 import BME280
  10. # Initialise the BME280
  11. bus = SMBus(1)
  12. bme280 = BME280(i2c_dev=bus)
  13. load_dotenv()
  14. outdoorName = os.getenv("BLE_PERIPHERAL_NAME")
  15. outdoorConnected = 0
  16. TEMP_UUID = "2A6E"
  17. PRESSURE_UUID = "2A6D"
  18. HUMIDITY_UUID = "2A6F"
  19. ALTITUDE_UUID = "2AB3"
  20. indoorValues = {
  21. "Temperature": 0,
  22. "Pressure": 0,
  23. "Humidity": 0,
  24. "Altitude": 0,
  25. }
  26. outdoorValues = {
  27. "Temperature": 0,
  28. "Pressure": 0,
  29. "Humidity": 0,
  30. "Altitude": 0,
  31. }
  32. def notification_handler(characteristic: BleakGATTCharacteristic, data: bytearray):
  33. global outdoorValues
  34. outdoorValues[characteristic.description] = struct.unpack("<i", data)[0]
  35. async def ble_task():
  36. global outdoorConnected
  37. while True:
  38. disconnect_event = asyncio.Event()
  39. device = await BleakScanner.find_device_by_name(outdoorName)
  40. if device is None:
  41. outdoorConnected = 0
  42. print("no device found, wait then scan again")
  43. await asyncio.sleep(30)
  44. continue
  45. try:
  46. async with BleakClient(device, disconnected_callback=lambda c: disconnect_event.set()) as client:
  47. outdoorConnected = 1
  48. await client.start_notify(TEMP_UUID, notification_handler)
  49. await client.start_notify(PRESSURE_UUID, notification_handler)
  50. await client.start_notify(HUMIDITY_UUID, notification_handler)
  51. await client.start_notify(ALTITUDE_UUID, notification_handler)
  52. await disconnect_event.wait()
  53. except Exception:
  54. outdoorConnected = 0
  55. print("exception while connecting or getting data")
  56. async def sensor_task():
  57. global indoorValues
  58. while True:
  59. temperature, pressure, humidity = bme280.read_compensated_data()
  60. altitude = bme280.altitude
  61. #print(_encode_value(pressure/100))
  62. indoorValues["Temperature"] = temperature * 100
  63. indoorValues["Pressure"] = pressure * 100
  64. indoorValues["Humidity"] = humidity * 100
  65. indoorValues["Altitude"] = altitude * 100
  66. await asyncio.sleep(1)
  67. conn = sqlite3.connect('./data/meteostanica.sqlite')
  68. cursor = conn.cursor()
  69. cursor.execute(
  70. """CREATE TABLE IF NOT EXISTS data (
  71. timestamp datetime default current_timestamp primary key,
  72. indoorTemp integer not null,
  73. indoorPressure integer not null,
  74. indoorHumidity integer not null,
  75. indoorAltitude integer not null,
  76. outdoorConnected integer not null,
  77. outdoorTemp integer not null,
  78. outdoorPressure integer not null,
  79. outdoorHumidity integer not null,
  80. outdoorAltitude integer not null
  81. );"""
  82. )
  83. conn.commit()
  84. async def write_task():
  85. while True:
  86. cursor.execute(f"""INSERT INTO data (
  87. 'indoorTemp', 'indoorPressure', 'indoorHumidity', 'indoorAltitude', 'outdoorConnected', 'outdoorTemp', 'outdoorPressure', 'outdoorHumidity', 'outdoorAltitude'
  88. ) VALUES (
  89. ?, ?, ?, ?, ?, ?, ?, ?, ?
  90. )""",
  91. (
  92. indoorValues["Temperature"],
  93. indoorValues["Pressure"],
  94. indoorValues["Humidity"],
  95. indoorValues["Altitude"],
  96. outdoorConnected,
  97. outdoorValues["Temperature"],
  98. outdoorValues["Pressure"],
  99. outdoorValues["Humidity"],
  100. outdoorValues["Altitude"]
  101. ))
  102. conn.commit()
  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())