| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- import asyncio
- from bleak import BleakClient, BleakScanner
- from bleak.backends.characteristic import BleakGATTCharacteristic
- import struct
- import sqlite3
- from dotenv import load_dotenv
- import os
- import smbus2
- import bme280
- # Initialise the BME280
- port = 1
- address = 0x76
- bus = smbus2.SMBus(port)
- calibration_params = bme280.load_calibration_params(bus, address)
- 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
- client = None
- try:
- while True:
- 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(10)
- continue
- try:
- async with BleakClient(device) as client:
- outdoorConnected = 1
- print(f"Connected to {outdoorName}")
- 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)
- while client.is_connected:
- await asyncio.sleep(1)
-
- except Exception as e:
- print(f"Connection lost or error: {e}")
- finally:
- outdoorConnected = 0
- print("Cleaning up connection state...")
- except asyncio.CancelledError:
- print("BLE task is being cancelled...")
- if client and client.is_connected:
- await client.disconnect()
- outdoorConnected = 0
- raise
- async def sensor_task():
- global indoorValues
-
- while True:
- data = bme280.sample(bus, address, calibration_params)
- indoorValues["Temperature"] = round(data.temperature * 100)
- indoorValues["Pressure"] = round(data.pressure * 100)
- indoorValues["Humidity"] = round(data.humidity * 100)
- indoorValues["Altitude"] = 0 # * 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 text not null,
- indoorPressure text not null,
- indoorHumidity text not null,
- indoorAltitude text not null,
- outdoorConnected integer not null,
- outdoorTemp text not null,
- outdoorPressure text not null,
- outdoorHumidity text not null,
- outdoorAltitude text 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()
- print(f"indoor: {indoorValues["Temperature"] / 100}°C, outdoor: {outdoorConnected} - {outdoorValues["Temperature"] / 100}°C")
- 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())
|