| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import asyncio
- from bleak import BleakClient, BleakScanner
- from bleak.backends.characteristic import BleakGATTCharacteristic
- import struct
- import sqlite3
- from dotenv import load_dotenv
- import os
- from smbus2 import SMBus
- from bme280 import BME280
- # Initialise the BME280
- bus = SMBus(1)
- bme280 = BME280(i2c_dev=bus)
- load_dotenv()
- outdoorName = os.getenv("BLE_PERIPHERAL_NAME")
- outdoorConnected = 0
- TEMP_UUID = "2A6E"
- PRESSURE_UUID = "2A6D"
- HUMIDITY_UUID = "2A6F"
- ALTITUDE_UUID = "2AB3"
- indoorValues = {
- "Temperature": 0,
- "Pressure": 0,
- "Humidity": 0,
- "Altitude": 0,
- }
- outdoorValues = {
- "Temperature": 0,
- "Pressure": 0,
- "Humidity": 0,
- "Altitude": 0,
- }
- def notification_handler(characteristic: BleakGATTCharacteristic, data: bytearray):
- global outdoorValues
- outdoorValues[characteristic.description] = struct.unpack("<i", data)[0]
- async def ble_task():
- global outdoorConnected
- while True:
- disconnect_event = asyncio.Event()
- device = await BleakScanner.find_device_by_name(outdoorName)
- if device is None:
- outdoorConnected = 0
- print("no device found, wait then scan again")
- await asyncio.sleep(30)
- continue
- try:
- async with BleakClient(device, disconnected_callback=lambda c: disconnect_event.set()) as client:
- outdoorConnected = 1
- await client.start_notify(TEMP_UUID, notification_handler)
- await client.start_notify(PRESSURE_UUID, notification_handler)
- await client.start_notify(HUMIDITY_UUID, notification_handler)
- await client.start_notify(ALTITUDE_UUID, notification_handler)
- await disconnect_event.wait()
- except Exception:
- outdoorConnected = 0
- print("exception while connecting or getting data")
- async def sensor_task():
- global indoorValues
-
- while True:
- temperature, pressure, humidity = bme280.read_compensated_data()
- altitude = bme280.altitude
-
- #print(_encode_value(pressure/100))
- indoorValues["Temperature"] = temperature * 100
- indoorValues["Pressure"] = pressure * 100
- indoorValues["Humidity"] = humidity * 100
- indoorValues["Altitude"] = altitude * 100
-
- await asyncio.sleep(1)
- conn = sqlite3.connect('./data/meteostanica.sqlite')
- cursor = conn.cursor()
- cursor.execute(
- """CREATE TABLE IF NOT EXISTS data (
- timestamp datetime default current_timestamp primary key,
-
- indoorTemp integer not null,
- indoorPressure integer not null,
- indoorHumidity integer not null,
- indoorAltitude integer not null,
- outdoorConnected integer not null,
- outdoorTemp integer not null,
- outdoorPressure integer not null,
- outdoorHumidity integer not null,
- outdoorAltitude integer not null
- );"""
- )
- conn.commit()
- async def write_task():
- while True:
- cursor.execute(f"""INSERT INTO data (
- 'indoorTemp', 'indoorPressure', 'indoorHumidity', 'indoorAltitude', 'outdoorConnected', 'outdoorTemp', 'outdoorPressure', 'outdoorHumidity', 'outdoorAltitude'
- ) VALUES (
- ?, ?, ?, ?, ?, ?, ?, ?, ?
- )""",
- (
- indoorValues["Temperature"],
- indoorValues["Pressure"],
- indoorValues["Humidity"],
- indoorValues["Altitude"],
- outdoorConnected,
- outdoorValues["Temperature"],
- outdoorValues["Pressure"],
- outdoorValues["Humidity"],
- outdoorValues["Altitude"]
- ))
- conn.commit()
- await asyncio.sleep(10)
- async def main():
- try:
- t1 = asyncio.create_task(ble_task())
- t2 = asyncio.create_task(sensor_task())
- t3 = asyncio.create_task(write_task())
- await asyncio.gather(t1, t2, t3)
- except asyncio.exceptions.CancelledError:
- pass
-
- asyncio.run(main())
|